如何以编程方式加载KnockoutJS组件
How to load a KnockoutJS component programmatically
我开始为select2创建一个名为"select-two"的ko组件,但我很快意识到,我有时需要在绑定注册后加载组件,以编程方式创建组件。
我试过添加一个新元素,但当然它不起作用,我猜它必须被重新绑定。
var sel2 = $("<select-two></select-two>") ;
$("#selectList").append(sel2) ;
有很多关于如何重新绑定整个视图模型的参考,但只是组件?我觉得这个人也有同样的问题:使用javascript加载knockoutjs组件
仅供参考,这是组件代码:
define([
'knockout',
'text!./select-two.html',
'select2'
], function (ko, templateMarkup, select2) {
ko.components.register('select-two', {
viewModel: function(params) {
var placeholder = params.placeholder;
var value = params.value;
ko.bindingHandlers.select2 = {
init: function (element, valueAccessor, allBindings, viewModel, bindingContext) {
$(element).select2({
placeholder: placeholder,
minimumInputLength: 1,
ajax: {
url: function (term, page) {
return '/models/autores/busqueda/' + term['term']
},
dataType: 'json',
quietMillis: 200,
processResults: function (data) {
return data;
}
},
dropdownCssClass: "bigdrop", // apply css that makes the dropdown taller
}
).on('change', function(event){
ds = $(element).select2('data')[0] ;
value['id'](ds['id']) ;
value['text'](ds['text']) ;
});
}
};
return{
}
},
template: templateMarkup
});
});
我的模板:<link rel="stylesheet" href="/assets/js/vendor/select2/dist/css/select2.css" />
<select class="form-control" data-bind="select2"></select>
和如何加载它:
<select-two id="authorSelect" params="placeholder: 'Pick an Author', value: autorSelectData" ></select-two>
ko.bindingHandlers.select2 = {
init: function (element, valueAccessor, allBindings, viewModel, bindingContext) {
var params = ko.unwrap(valueAccessor());
$(element).select2({
placeholder: params.placeholder,
minimumInputLength: 1,
data: params.data
}).on('select2:select', function(e) {
params.value(e.params.data.text);
});
$(element).select2('val', params.value); // set initial value
}
};
ko.components.register('select-two', {
viewModel: function(params) {
this.value = params.value;
this.data = params.data;
},
template: '<select class="form-control" style="width: 200px;" data-bind="select2: ' +
'{placeholder: ''Pick a fruit'', value: value, data: data}">' +
'</select>'
});
var app = {
newSelect: function(){
var cont = $("<p></p>") ;
var sel2 = $("<select-two></select-two>") ;
ko.applyBindings({}, sel2[0]) ;
cont.append(sel2) ;
$("#select-list").append(cont) ;
},
autorSelectData: ko.observable(null),
options: ['apple','pear','peach','mango','grape']
};
ko.applyBindings(app);
<link href="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.0/css/select2.min.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.0/js/select2.min.js"></script>
Just the binding: <select class="form-control" style="width: 200px;"
data-bind="select2: {placeholder: 'Pick a fruit', value: autorSelectData, data: options}">
</select><br>
With component: <select-two params="value: autorSelectData, data: options"></select-two>
<p>Adding Selects</p>
<div id="select-list">
</div>
<input type="button" data-bind="click: newSelect()" value="New Select" id="new-select" />
我猜它必须重新绑定。
请记住,当您考虑将重新绑定作为解决方案时,在99%的情况下您应该重新考虑您的方法。
以编程方式创建组件。
如果你遵循MVVM/MVC准则,你应该永远不必这样做。所有数据模型/视图的结构都是预定义的;只有它们的内容可以改变。
你不该做什么?
- 在组件中注册自定义绑定,这意味着每次创建组件实例时,它都会被重新注册。
- 在组件模板中链接样式表,这意味着每次创建组件实例时都会加载样式表(而不是一次)。
- 使用
change
事件,而select2文档显示您必须使用select2:select
。
下面是代码的简化版本(例如:(数据数组而不是AJAX),展示了它是如何使用(1)绑定和(2)封装组件工作的。它是否仍然不起作用,如果是,什么不起作用?
ko.bindingHandlers.select2 = {
init: function (element, valueAccessor, allBindings, viewModel, bindingContext) {
var params = ko.unwrap(valueAccessor());
$(element).select2({
placeholder: params.placeholder,
minimumInputLength: 1,
data: params.data
}).on('select2:select', function(e) {
params.value(e.params.data.text);
});
$(element).select2('val', params.value); // set initial value
}
};
ko.components.register('select-two', {
viewModel: function(params) {
this.value = params.value;
this.data = params.data;
},
template: '<select class="form-control" style="width: 200px;" data-bind="select2: ' +
'{placeholder: ''Pick a fruit'', value: value, data: data}">' +
'</select>'
});
var app = {
autorSelectData: ko.observable(null),
options: ['apple','pear','peach','mango','grape']
};
ko.applyBindings(app);
<link href="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.0/css/select2.min.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.0/js/select2.min.js"></script>
Just the binding: <select class="form-control" style="width: 200px;"
data-bind="select2: {placeholder: 'Pick a fruit', value: autorSelectData, data: options}">
</select><br>
With component: <select-two params="value: autorSelectData, data: options"></select-two>
相关文章:
- 如何使用url加载程序在webpack中导入多个图像
- 如何在生成下载文件时显示加载动画
- 有没有任何方法可以将控制器从文件加载到ui路由器$stateProvider中
- 无法在通过jQuery的ajax加载的页面中执行javascript
- Emberjs应用程序加载在除Index之外的所有路由上
- 在foreach中加载所有项后,Knockoutjs组件回调
- 使用javascript加载knockoutjs组件
- 在 KnockoutJS 应用程序中将 AngularJS 应用程序作为 iFrame 加载
- 在使用 KnockoutJS 从 API 加载字段后,将字段添加到 observableArray
- 使用 knockoutjs 加载绑定
- KNockoutJS-引导模式未正确加载
- KnockoutJS-将值加载到下拉列表.“选定值”始终为null
- knockoutjs的数据加载模式
- 如何用RequireJS加载KnockoutJS自定义函数
- 使用knockoutjs延迟加载图像
- 使用KnockoutJS和Jade加载json文件
- 如何以编程方式加载KnockoutJS组件
- KnockoutJS -在每个绑定中异步加载
- KnockoutJS 自定义组件加载器未执行“loadViewModel”
- 延迟加载knockoutjs, bookmarklet失败