对于大多数JS框架和库,它们带来的价值通常是关于如何构建应用程序(Backbone,React)的新结构,或者有效地启动语言的新想法(Angular),或者只是他们提供的方法经过了充分的测试,快速且非常方便(jQuery)。
通常他们提供的想法和方法都非常直接地使用JavaScript,但是有一个非常聪明的团队,它可以找到有趣的方法来做你能想到的事情,并对胆量如何运作有一个可靠的猜测。
但是,我一直无法通过双向绑定JS模型来查看组件的能力。这项功能的核心是什么秘诀使这项工作?从用户输入更改内部变量很简单,但反过来呢?当JS变量何时发生变化以便立即更新显示时,您将如何“知道”?当然它不能轮询,那么呢?
答案 0 :(得分:2)
每当你的JS块运行该角度触发时,它将在块完成执行时运行摘要循环。这基本上会检查可能已更改的所有值,并且需要更新视图。
如果角度没有触发代码,那么它就不会知道某些内容可能会发生变化,因此您的绑定可能会失去同步。例如,如果你运行这样的东西
setTimeout(function() {$scope.myValue = '123'});
Angular不知道myValue
发生了变化,实际上它不会更新视图。这就是为什么Angular拥有自己的服务来做所有事情的原因。例如$timeout
或$http
。
如果您有一些Angular不知道的回调函数,您可以通过调用$scope.$apply()
答案 1 :(得分:1)
有几种方法可以做到这一点。 Object.observe很棒,但缺乏良好的支持。您也可以轮询值,保留对象的第二个副本以进行比较。您也可以编写自己的显式set / get方法来更新模型,如骨干。
我经常使用的一个简洁方法是使用getter / setter来保持模型与dom同步:
//a demo "model" of data:
model = {
name: "Fred"
};
function change(k,v){alert([k,v]);} // a stand-in change monitor for demo
// iterate model and replace values with getter/setter combos:
Object.keys(model).forEach(function(key) {
var val = model[key];
delete model[key];
Object.defineProperty(model, key, {
get: function() {
return val;
},
set: function(v) {
val = v;
change(key, val);
} //call change upon setting
});
change(key, val); //update view "onload"
}); // alerts "Fred";
//update model (fires change() with "name" and "sally" arguments:
model.name="sally"; // alerts "sally";
更改功能非常简单,对于您的情况应该只找到绑定到键的元素。 这里的优点是你不需要特殊的自定义CRUD方法,你可以像1999年那样通过赋值来修改对象属性。它也没有轮询,并且一直正常工作到IE9和任何其他ES5环境。这是在没有自定义方法的情况下绑定JS> DOM(afaik)的最简单方法。
它确实有一些限制:嵌套对象很难获得/设置,你不能一次完成整个对象,你只能观察"原语。数组也是一个问题:你无法用getter / setter替换expando属性而没有副作用。但是,在相对平坦的JSON安全数据集合中,get / set是一个魅力,不需要复杂的库来实现。
使用此方法结帐完整示例:http://pagedemos.com/xg3szbguqnwu/4
答案 2 :(得分:0)
我可以谈谈它在Backbone中的表现,后者对数据绑定的看法相对较低。
它是1.控制属性设置器方法的库的组合2.当属性改变时(例如通过调度事件)调用回调函数以便更新UI。
基本伪代码是这样的:
class Model:
method set(name, value):
if value != this.attributes[name]
this.triggerEvent('change', name, value)
this.attributes[name] = value
m = new Model()
someInputWidget.onEvent('userChangedInput', function(value) {
m.set(someInputWidget.name, value)
})
m.onEvent('change', function(name, value) {
getInputWidgetByName(name).setValue(value)
})
Backbone没有对UI进行任何数据绑定,但您可以参考Backbone的annotated source来实现事件调度实现。