2016-02-11 49 views
1

我有一个AngularJS服务定义如下:为什么绑定在第二级而不是在第一级上起作用?

function testService(testProvider) { 
    var ref = this; 
    ref.firstLevel = {}; 
    ref.secondLevel = {}; 

    initialize(); 

    function initialize() { 
    testProvider.getData().then(function(result) { 
     ref.firstLevel = result; 
     ref.secondLevel.testData = result; 
    }); 
    } 
} 

testProvider约为$ http.get一个简单的包装,从JSON获取数据。控制器上复制这些属性:

function testController(testService) { 
    var vm = this; 

    vm.firstLevel = testService.firstLevel; 
    vm.secondLevel = testService.secondLevel; 
} 

当我创建我的模板绑定,第二级的作品,第一级没有。

<!-- Doesn't work --> 
<p>{{vm.firstLevel.testProperty1}}</p> 
<p>{{vm.firstLevel.testProperty2}}</p> 

<!-- Does work --> 
<p>{{vm.secondLevel.testData.testProperty1}}</p> 
<p>{{vm.secondLevel.testData.testProperty2}}</p> 

的工作示例,请参见本Plunker:

https://plnkr.co/edit/pLInqcaJNhhbQWbvTUEE

为什么不第一级例子工作?

回答

2

这是因为当你用Javascript重写一个对象时,你实际上失去了对实际对象的引用。

testProvider.getData().then(function(result) { 
    ref.firstLevel = result; 
    ref.secondLevel.testData = result; 
}); 

这里ref.firstLevel = result覆盖对已初始化为{}的对象的引用。此行后面的任何数据绑定都会丢失。

而通过做ref.secondLevel.testData = result,您不会重写对象,而只是通过添加额外的键testData来修改对象。因此,引用仍然保留,AngularJS绑定也一样。

为了更加清楚,请参阅this answer

+0

这是我最初的理论,但我认为*我已经排除了测试。但是我对你的(和我的)理论有更多的信心,而不是我一起入侵的快速测试:) – Daan

+1

定时在这里很重要:首先对象在服务中获得初始化,然后*控制器将引用复制到对象中*然后* Promise解析,全部替换对象。在我的(不正确的)测试中,我替换了服务的初始化阶段中的对象,这是在**控制器获取其引用之前的**,所以似乎都工作正常。 – Daan

+1

确实是这样!当你提到你的错误测试时,我有点怀疑你会这样做。 我在想,如果我们需要重写对象并保留其引用并学习angular.copy,那么我们可以这样做:'angular.copy(source,[destination]);'。从来不知道它可能需要第二个参数。 – hallucinations

相关问题