这是一些简单的代码来演示"后现代"淘汰模板的功能。当我点击按钮时,警告框会显示两次,而它应该只显示一次。
您可以在下面找到完整的代码。知道警报框出现两次的原因吗?
<!DOCTYPE html>
<html>
<head>
<meta charset="ISO-8859-1">
<title>Insert title here</title>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.3.0/knockout-min.js"></script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.0.0-alpha1/jquery.min.js"></script>
</head>
<body>
<div data-bind="component: {name : 'foo-component', params: {onLoad: fooLoadedCallback}}"></div>
<!--foo-component params="onLoad: fooLoadedCallback"></foo-component-->
<script type="text/javascript">
ko.components.register('foo-component', {
//inner view model, only for this component in the template below.
viewModel: function(params) {
return {
status: ko.observable('Constructed'),
//this is called only after the template is rendered. This is called due to a statement in template.
componentLoaded: function () {
if (params.onLoad) {
params.onLoad(this);
}
$('button').click(function(){
alert("Rendered.");
});
}
};
},
template: '<h1>Hello</h1><br><button>Click me</button><br><span data-bind="text: status">Template</span>'
+'<span data-bind="template: { afterRender: componentLoaded() }"></span>',
});
//outer view model, for the div element.
var outerViewModel = {
fooLoadedCallback: function(viewModel) {
viewModel.status('Rendered!');
},
};
ko.applyBindings(outerViewModel);
</script>
</body>
</html>
答案 0 :(得分:2)
您收到两个警报,因为您的componentLoaded
方法被调用两次,将多个侦听器附加到该按钮。
我相信你的问题出在<span data-bind="template: { afterRender: componentLoaded() }"></span>
部分。
例如,如果您使用template
更改with
,则代码可以正常运行。有一个例子:
template: '<h1>Hello</h1><br><button>Click me</button>'
+ '<br><span data-bind="text: status">Template</span>'
+ '<span data-bind="with: { afterRender: componentLoaded() }"></span>'
但是,请记住,我从未使用过Knockout,并且无法告诉您这是否正确。我只是指出发生了什么。
答案 1 :(得分:2)
afterRender
总是被调用两次。一次是占位符元素,一次是真实的东西。使用once之类的内容可以防止它被调用两次,或者可以安全地多次调用componentLoaded
。
此外,$('button')
将为您提供DOM中当前的每个按钮。如果你有多个,它会将点击添加到所有这些。