One, several ways to realize two-way binding
There are several mainstream MVC (VM) frameworks that implement one-way data binding, and the bidirectional data binding I understand is nothing more than adding a change (input) event to an INPUT element (input, textare, and so on) on a one-way binding to dynamically modify the model and view, is not much advanced. So it doesn't have to be too much to be true one-way or two-way binding.
There are several ways to implement data binding:
Publisher-subscriber mode (backbone.js)
Dirty value Check (angular.js)
Data Hijacking (Vue.js)
Publisher-subscriber mode: generally through sub, pub way to achieve data and views of the binding monitoring, update the data way usually, there is vm.set(‘property‘, value)
an article about the more detailed, interested to point here
This way is too low now, we would like to vm.property = value
update the data in this way, while automatically updating the view, so there are two ways
Dirty value Check: angular.js is the way to determine whether to update the view by detecting the dirty value than whether the data is changed, the simplest way is to check the setInterval()
data changes by timed polling, of course, Google is not so low, Angular only enters the dirty value detection when the specified event is triggered, roughly as follows:
DOM events, such as user input text, click Buttons, and so on. (Ng-click)
XHR Response Event ($http)
Browser location Change event ($location)
Timer event ($timeout, $interval)
Execute $digest () or $apply ()
Data hijacking: Vue.js is the use of data hijacking combined with the Publisher-subscriber mode, through the Object.defineProperty()
hijacking of the various attributes, the setter
getter
data changes when the message to subscribers, triggering the corresponding monitoring callback.
Second, vue.js realization of the principle of two-way binding (Object.defineproperty ()) understand the role of Object.defineproperty
An object is an unordered collection of multiple name/value pairs. Each property in the object corresponds to a value of any type.
Definition objects can be in the form of constructors or literals:
var obj = new Object; //obj = {}obj.name = "张三"; //添加描述obj.say = function(){}; //添加行为
In addition to the above methods of adding properties, you can also use Object.defineproperty to define new properties or to modify existing properties.
Object.defineproperty ()
Grammar:
Object.defineProperty(obj, prop, descriptor)
Parameter description:
OBJ: Required. Target Object
Prop: Required. The name of the property that needs to be defined or modified
Descriptor: Required. Attributes owned by the target property
return value:
The object passed into the function. That is, the first parameter, obj
For attributes, we can set some properties for this property, such as whether it is read-only or not, and whether it can be used for . in or Object.keys () traversal.
Adds an attribute description to an object's properties, currently available in two forms: Data description and accessor description.
Data Description
When modifying or defining a property of an object, add some attributes to this property:
var obj = {Test"Hello"}Property added attribute description for an existing objectObject.defineproperty (obj,"Test", {configurable:true | false, enumerable:true | false, value: Any type of value, writable: true | false}); //object property Description of newly added properties object.defineproperty (Obj," NewKey ", {configurable:true | false, enumerable:true | false, value: Any type of value, writable:true | false})
The properties in the data description are optional and look at the effect of setting each property.
value
property, you can make any type of value, default to undefined
var obj = {}//第一种情况:不设置value属性Object.defineProperty(obj,"newKey",{});console.log( obj.newKey ); //undefined------------------------------//第二种情况:设置value属性Object.defineProperty(obj,"newKey",{ value:"hello"});console.log( obj.newKey ); //hello
writable
Whether the value of the property can be overridden. Set to True can be overridden, set to false, and cannot be overridden. The default is False.
var obj = {}The first case: writable is set to false and cannot be overridden.Object.defineproperty (obj, "NewKey", {value: "Hello", writable:false}); //Change the value of NewKey Obj.newkey = "changed value"; //hello//the second case: writable set to True, you can override object.defineproperty (Obj, "NewKey", { value: "hello", writable:true}"; //Change the value of NewKey Obj.newkey = "changed value"; //change value
Enumerable
Whether this property can be enumerated (using for...in or Object.keys ()). Set to true can be enumerated; set to false, cannot be enumerated. The default is False.
var obj = {}The first case: enumerable is set to false and cannot be enumerated.Object.defineproperty (obj,"NewKey", {Value"Hello",Writable:Falseenumerable:false}); //enumeration object's properties for (var attr in obj) {console.log (attr);} //the second case: enumerable is set to true and can be enumerated. object.defineproperty (Obj, "NewKey", { value: "hello", writable:false, enumerable:true}); //enumeration object's properties for (var attr in obj) {console.log (attr); //newkey}
Configurable
Whether you can delete the target property or whether you can modify the attribute's properties (writable, configurable, enumerable) again. Set to True can be deleted or can be reset attribute, set to False, cannot be deleted or can not be re-set attributes. The default is False.
This attribute plays two roles:
Whether the target property can be deleted using delete
Whether the target property can set the attribute again
-----------------test whether the target property can be deleted------------------------var obj = {}The first case: configurable is set to false and cannot be deleted.Object.defineproperty (obj,"NewKey", {Value"Hello",Writable:FalseEnumerableFalseConfigurable:False});Delete PropertyDelete Obj.newkey;Console.log (Obj.newkey);HelloThe second case: configurable is set to true and can be deleted.Object.defineproperty (obj,"NewKey", {Value"Hello",Writable:FalseEnumerableFalseConfigurable:true});Delete PropertyDelete Obj.newkey;Console.log (Obj.newkey);Undefined-----------------Test if the attribute can be modified again------------------------var obj = {}The first case: configurable is set to false and the attribute cannot be modified again.Object.defineproperty (obj,"NewKey", {Value"Hello",Writable:FalseEnumerableFalseConfigurable:False});Re-modify attributesObject.defineproperty (obj,"NewKey", {Value"Hello",Writable:TrueEnumerableTrueConfigurable:true});Console.log (Obj.newkey);Error: uncaught Typeerror:cannot redefine Property:newkeyThe second case: configurable is set to True to modify the attribute again.Object.defineproperty (obj,"NewKey", { value:"Hello", writable:false, enumerable:false, configurable:true} ); //re-Modify the attribute Object.defineproperty (obj,"NewKey", { value:"Hello", writable:true, Enumerable:True, configurable:true}); Console.log (Obj.newkey); //hello
In addition to setting attributes for a newly defined property, you can also set properties for an existing property
//定义对象的时候添加的属性,是可删除、可重写、可枚举的。var obj = { test:"hello"}//改写值obj.test = ‘change value‘;console.log( obj.test ); //‘change value‘Object.defineProperty(obj,"test",{ writable:false})//再次改写值obj.test = ‘change value again‘;console.log( obj.test ); //依然是:‘change value‘
Tip: Once you use Object.defineproperty to add properties to an object, if you do not set properties for the attribute, then configurable, enumerable, and writable are the default false
var obj = {};//定义的新属性后,这个属性的特性中configurable,enumerable,writable都为默认的值false//这就导致了neykey这个是不能重写、不能枚举、不能再次设置特性//Object.defineProperty(obj,‘newKey‘,{});//设置值obj.newKey = ‘hello‘;console.log(obj.newKey); //undefined//枚举for( var attr in obj ){ console.log(attr);}
Summary of features set:
Value: Sets the values of the property
Writable: Whether the value can be overridden. true | False
Enumerable: Whether the target property can be enumerated. true | False
Configurable: Whether the target property can be deleted or can be modified again if the attribute is true | False
Accessor Description
When using accessors to describe the attributes of a property, the following attribute properties are allowed to be set:
var obj = {};Object.defineProperty(obj,"newKey",{ get:function (){} | undefined, set:function (value){} | undefined configurable: true | false enumerable: true | false});
Note: When using Getter or setter methods, the writable and value properties are not allowed
Getter/setter
You can provide a Getter/setter method when you set or get the value of a property of an object.
Use the Get/set property in the attribute to define the corresponding method.
var obj = {};var initvalue = ' hello '; object.defineproperty (Obj, "NewKey", { get:function ( //the function triggered when the value is obtained return InitValue; }, set:function (value" {//the function that is triggered when the value is set, the new value set by the parameter value to get InitValue = value;}}); //get the value console.log (Obj.newkey); //hello//set value Obj.newkey = console.log (Obj.newkey); //change value
Note: Get or set does not have to appear in pairs, either write one. If you do not set the method, the default value for get and set is undefined
Configurable and enumerable with the above usage.
Compatibility
IE8 can only be used on DOM objects, attempting to use Object.defineproperty () on native objects will give an error.
Ref: 1190000007434923
Vue.js the principle of implementing two-way binding