如何将指令模型绑定到异步服务数据

How to bind directive model to async service data

本文关键字:异步 服务 数据 绑定 模型 指令      更新时间:2023-09-26

我正在尝试做简单的事情 - 将指令的模型绑定到服务的数据。在服务的数据异步加载(通过$timeout或$http请求)之前,它根本不会更新指令的模型。

现场示例 http://codepen.io/snater/pen/IjvFa

资料来源:

<div ng-app="asyncServiceTest" ng-controller="testController">
    <bind-to-service></bind-to-service>
</div>

app = angular.module "asyncServiceTest", []
app.directive "bindToService", ["dataService", (dataService) ->
    restrict: "E"
    scope: {}
    template: "<div>{{ test }}</div>"
    link: (scope) ->
        scope.test = dataService.test
]
app.factory "asyncService", ["dataService", "$timeout", (dataService, $timeout) ->
    load: ->
        dataService.test = "SYNC DATA!"  # Works fine
        $timeout ->
            dataService.test = "ASYNC DATA!" # Doesn't work ((
        , 2000
]
app.factory "dataService", ->
    test: "Init Data"
app.controller "testController", ["$scope", "asyncService", ($scope, asyncService) ->
    asyncService.load()
]

asyncService 中调用$rootScope上的$apply不起作用,这是意料之中的,但我已经尝试过了。

由于 javascript 的原型性质,在进行绑定时应该使用 . 表示法。我已经更新了实时示例。

http://codepen.io/anon/pen/jverH

基本上我把服务改成了

app.factory "dataService", ->
    test: {data:"Init Data"}

并做了其他相应的更改。

基本上当你这样做时

scope.test = dataService.test;

您刚刚将范围test值分配给了一个字符串。但是,对数据服务test字符串所做的任何更改都不会按预期反映出来。在编程术语中,它就像按值传递。

阅读作用域原型继承及其工作原理,了解为什么您所做的不起作用。

代码的主要问题是,当数据使用异步方法更改时,您尝试更改测试对象的直接引用。这会导致问题,因为您将测试对象"REFERENCE"与指令的模型绑定在一起,因此不应更改它以使数据绑定处于活动状态。如果更改引用,则绑定将丢失。

因此,将数据保存在测试对象的属性中,如"test.value",并更改值而不是测试引用。

以下是更新的代码:

app = angular.module "asyncServiceTest", []
app.directive "bindToService", ["dataService", (dataService) ->
    restrict: "E"
    scope: {}
    template: "<div>{{ test.value }}</div>"
    link: (scope) ->
        scope.test =  dataService.test;
]
app.factory "asyncService", ["dataService", "$timeout", (dataService, $timeout) ->
    load: ->
        dataService.test.value = "SYNC DATA!"
        $timeout ->
            dataService.test.value = "ASYNC DATA!"
        , 2000
]
app.factory "dataService", ->
    test: {value:""};
app.controller "testController", ["$scope", "asyncService", ($scope, asyncService) ->
    asyncService.load()
]

以下是更新的链接:

http://codepen.io/kalyansriram/pen/BCmla