手机版

谈Angularjs中不同类型的双向数据绑定

时间:2021-08-31 来源:互联网 编辑:宝哥软件园 浏览:

Angularjs1中两种不同的双向数据绑定。X

说说Angular JS 1里面那些该死的东西。X.

1.html和控制器之间的双向数据绑定

html-Controller的双向数据绑定在开发中很常见,也是Angularjs1.x的宣传点之一,使用中问题不多。

1.1数据从html流向控制器

也就是说,从视图层到模型层,原生html需要使用表单元素(比如输入标签)来收集用户输入信息。在Angularjs中,通过在表单元素上使用ng-model标签,当用户输入信息时,用户输入的信息被同步分配给控制器中的变量:

body ng-app=' myapp ' div id=' main ' ng-controller=' myctrl ' p change输出值:/p输入类型=' text ' ng-model=' testinfo . content ' ng-change=' show input()'/div脚本src='http:/angular.min.js'/script脚本angular.module('myApp ',[])。控制器(' myCtrl ',['$scope ',函数($ scope){ $ scope . showinput=function(){ console . log($ scope . testinfo . content);} }]);/script/body通过在页面上输入1234567可以看到每次在页面上输入数字时,控制台输出的$scope,testInfo.content的值与页面的值是一致的:

1.2数据从控制器流向html

也就是从模型层到数据层,当控制器中的数据模型变量发生变化时,Angularjs会根据数据模型的值改变ng-model指令绑定的表单元素的值,也可以使用ng-bind指令被动获取来自控制器的数据流。

我们编写以下演示进行测试:

body ng-app=' myapp ' div id=' main ' ng-controller=' myctrl ' button ng-click=' add()' 1/button P change输出值:/P输入类型=' text ' ng-model=' test info . content ' pLabel由ng-bind绑定:/P ng-bind=' test info . content '/P/div script src=' http 3360。/angular . min . js '/script script angular . module(' myapp ',[])。控制器(' myctrl ',['$ scope ',函数($ scope){//initialize $ scope . testinfo={ content : 0 } $ scope . add=function(){ $ scope . testinfo . content=console . log($ scope . testinfo . content);} }]);在/script/bodydemo中,每次单击1按钮,$scope.testInfo.content的值都会增加1,我们可以在页面上看到结果:

1.3你刷你的视图。

让我们看看第一个该死的例子。除了鼠标点击触发模式改为定时器自动触发之外,演示与上述非常相似:

body ng-app=' myapp ' div id=' main ' ng-controller=' myctrl ' button ng-click=' add()' 1/button P change输出值:/P输入类型=' text ' ng-model=' test info . content ' pLabel由ng-bind绑定:/P ng-bind=' test info . content '/P/div script src=' http 3360。/angular . min . js '/script script angular。模块(' myapp ',[])。控制器(' myctrl ',['$ scope ',函数($ scope) {//initialize $ scope。testinfo={ content :0 }//定期增加setinterval (function () {$ scope。testinfo.console . log(' $ scope . testinfo . content的值现在是: ',$ scope . testinfo . content);},1000) }]);/script/body您会发现数据模型一直在更改,但页面尚未刷新:

这是Angularjs1双向数据绑定的第一个坑。x,您会发现绑定在$scope上的数据模型和html中显示的内容有时并不实时相关。其实这和Angularjs1的实现机制有关。X

如果我们自己想想,javascript中变量的值已经改变了。现在我们应该做什么来将这个值同步到html页面?我们需要得到这个DOM元素,然后改变它的innerHTML属性,如果它是一个表单元素,修改这个值。事实上,Angularjs也做了同样的事情,只是它使用了自己的封装方法—— $apply()。那么这里的问题是,在setInterval的回调函数中修改数据模型的值时,不会触发$apply()方法更新视图,而是通过调用Angularjs封装的ng-*方法(例如ng-click方法)修改视图模型时,会自动触发$apply()方法,同步刷新视图。

解决方案1

使用Angularjs封装的$interval服务来实现定时任务,感兴趣的读者可以查看Angularjs源代码中的$intervalProvider,找到那个$rootScope。$apply()在方法的末尾被调用。

解决方案2

如果仍然使用javascript的本机计时方法,则需要手动调用$scope。$apply()方法,以便将数据模型的更改同步到html页面。

两个。控制器和指令之间的双向数据绑定

除了controller和html之间的双向绑定,Angularjs中还有另一个双向数据绑定,即controller和directive之间的绑定。捆绑有很多种形式。我们先来看看最常见的双向绑定。

2.1指令中的双向数据绑定

设置自定义指令的作用域参数时,可以通过将属性值设置为=,实现双向数据绑定。在这里,应用编程接口解释道:

父控制器中的指定变量将与自定义指令的链接函数中的变量进行交互。

在下面的例子中,我们将看到控制器中的数据模型$scope.testInfo.content的值和自定义指令中的scope.pagination是如何相互作用的,以及这里的绑定是否真的像定义的那样是双向的。示例界面如下(演示源代码请参考随附的demo.html文件):

每次单击1按钮,Scope.testInfo.content的值都会增加1。每次点击show $scope.testInfo,控制台都会打印出$scope.testInfo的值,每次点击标签上的数字,就会打印出自定义指令中scope . paging的值,该值会自动增加。下一步测试操作将按照以下流程进行:

单击1按钮五次,然后单击数字标签五次。单击show $scope.testInfo按钮2.2。你为什么不再次刷新它

按照上一节中的步骤,让我们见证双向数据绑定中的另一个闹鬼事件:

点按“1”按钮五次,然后点按数字标签五次

结果是:

我们可以看到,当第一次点击数字标签时,控制台在链接函数中键入了scope . paging的值为5,这意味着$scope.testInfo.content的值被传递给了自定义指令中的scope . paging,这意味着数据从控制器流向了指令。当我们四次(总共五次)点击数字标签时,从控制台可以看到scope.pagination的值变成了10,但是在页面上使用ng-bind指令得到的结果仍然是5。也就是说,数据从不从指令流向控制器。有没有被骗的感觉?别担心,继续看。

单击显示$scope.testInfo按钮

结果是:

当我们点击show $scope.testInfo时,控制台打印出$scope.testInfo.content的值为5,所以证据确凿,双向数据绑定表述清楚。但是,当自定义指令中的scope.pagination改变时,$scope.testInfo.content不会随之改变。但是!我们会发现点击这个show $scope.testInfo后,页面上ng-bind绑定的值变成了10。也就是说,数据从指令流回控制器。

官方建议是使用$watch方法跟踪范围内的变量。当我们这样做时,我们会发现$watch函数只能通过修改控制器中的数据模型和更新视图来跟踪影响link函数中变量的行为。

这是Angularjs1中的第二个坑。x双向数据绑定。控制器和指令中所谓的双向数据绑定,无法跟踪指定变量的所有变化,也不是同步完成的。

其实这里的问题还是和Angularjs的运行机制有关,解决方法如下:

解决方案1

使用自定义指令的templateUrl属性替换当前指令的模板,使用ng-click指令绑定一个click响应函数,更改响应函数中scope.piganation的值。

解决方案2

在手动绑定监听回调中,修改自定义指令范围内的变量后,使用范围。方法通知其父控制器,并使用$scope。$on()方法监听同名事件并修改相应的数据模型值。

解决方案3

每当自定义指令中的变量值发生变化时,调用作用域。$apply()方法将指令中的变量值同步到控制器的数据模型和页面。

三.原则和实践总结

3.1 Angular JS中双向数据绑定的基本原理

Angularjs中的双向数据绑定是通过一种叫做*‘脏检查’的机制实现的。

基本流程如下。每当我们使用ng-model或ng-bind指令将数据模型中的变量值与html页面上的标签内容相关联时,Angular都会将这些变量放入WatchCollection集合中,并自动帮助我们监控这些变量。每次WatchCollection中的变量发生变化时,Angular都会遍历WatchCollection,查看其他受监控的变量是否受到影响。每当变量受到影响时,Angular将在遍历后再次遍历。直到WatchCollection中的变量经过一定的遍历后没有变化,Angular才会认为当前的变化已经稳定下来,然后数据模型的变化就会同步到DOM元素中,从而实现数据绑定。

我们可以将WatchCollection理解为当前页面的抽象,它包含了页面中可能发生变化的所有部分。

3.2双向数据绑定的实践经验

为了在Angularjs项目中更稳定地使用双向数据绑定,笔者的建议是:

在Angularjs项目中,尽可能按照Angular告诉您的方式编写所需的函数。

当使用双向数据绑定时发生异常时,我们可以回顾上述场景:

使用本机计时器(您应该在Angular中使用$interval,$timeout服务),使用类本机方法(bind)向元素添加事件侦听器,并修改回调函数中变量的值(在Angular中,您应该使用ng-click来监视click事件).你会发现,每当你不以Angular的方式编写代码或按照模块设计的初衷使用代码时,这很容易理解。如果您没有按照Angular要求的方式编写代码,为什么要期望它100%正确地响应您的代码呢?对于以上两种数据绑定中的问题的解决方案,上面已经提到过了,这里就不再赘述。

很多人都听过‘尽量不要在控制器中操作DOM’这句话。事实上,这并不意味着在控制器中操作DOM会导致程序报告错误。相反,这意味着如果您同时使用jQuery和Angular系统来管理您的代码,但是您没有以官方指定的方式避免它们之间的冲突,代码可能会变得不稳定。想想腾讯电脑管家和360保安把你电脑卡死的场景,你就明白结果了。

四.总结——所谓的大师

以上就是本文的全部内容。希望对大家的学习有帮助,支持我们。

版权声明:谈Angularjs中不同类型的双向数据绑定是由宝哥软件园云端程序自动收集整理而来。如果本文侵犯了你的权益,请联系本站底部QQ或者邮箱删除。