2016-02-11 2 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 разрешает, заменяя объект alltogether. В моем (некорректном) тесте я заменил объект в фазе инициализации Сервиса, который ** до ** контроллер получает свою ссылку, поэтому все, казалось, работало нормально. – Daan

+1

Действительно! Я догадывался, что вы будете делать что-то подобное, когда расскажете о своем неправильном тесте. Я думал, что если нам нужно будет переписать объект, сохраняющий его ссылку и узнав, что угловой.copy имеет версию, которая позволяет нам это сделать: 'angular.copy (source, [destination]);'. Никогда не знал, что это может взять второй параметр. – hallucinations

Смежные вопросы