2016-02-11 3 views
0

Я думаю, что я просто потерял несколько часов до точки в AngularJS.AngularJS: привязка данных и точка-обозначение

This Plunker демонстрирует проблему, которая до сих пор раздражает меня:

app.controller('MainCtrl', function($scope, ValueService) { 
$scope.obj= ValueService.getObject(); // Output: {"string": "New!!!"} 
$scope.val = ValueService.getVal(); // Output: "init" 
ValueService.setVal(); 

}) 
.service('ValueService', function(){ 
var output= {string: 'init'}; 

this.setVal = function(val){ 
output.string = 'New!!!'; 
}; 

this.getObject = function(){ 
return output; 
}; 

this.getVal = function(){ 
return output.string; 
}; 

return this; 
}); 

Я знаю, что я должен использовать объекты при использовании ng-model (дот-нотация помогает решению проблем эталонных при поиске вложенных областей). Однако я не знал, что это относится и к простейшему случаю, подобному этому. Я был еще более удивлен, потому что ссылка на мой объект остается в такте, если я использовать массивы (и изменить его с нажатием/сращивания): another Plunker

Может кто-нибудь объяснить, почему именно привязка данных не работает для value больше, когда я переназначить Это? Есть ли способ привязки к значению без передачи объекта-обертки из службы?

+1

Создайте плункер, который показывает, что привязка не работает при переназначении. Тогда мы можем помочь. –

+0

OP уже разместил ссылку на ссылку _another Plunker_. – Jai

+0

Ссылка на «другой Plunker» может быть более понятной, но на самом деле вызов 'setVal()' в первом Plunker уже является переназначением, которое не было захвачено '$ scope.val' –

ответ

0

Функция getVal возвращает значение output.string AT THAT POINT IN TIME. вы присваиваете это значение своей переменной $ scope.val. поэтому в этот момент времени output.string является «Init», следовательно, значение $ scope.val является «Init» Это никогда не изменится, почему бы вам? Это не имеет никакого отношения к двунаправленной привязке данных или точечной привязке angularjs. Вы просто назначаете значение «Init» в значение $ scope.val и никогда не меняете его снова, это чистая javascript-вещь, которая происходит здесь.

+0

Итак, это действительно упрощенный пример. В моем исходном коде «строка» также является объектом, и она ведет себя одинаково. Я действительно думаю, что это скорее проблема с объектными ссылками, чем разница между строками и объектами. –

+0

мой ответ также применяется, если для output.foo, foo - это объект вместо строки, да. так что же это ваш вопрос? , если вы замените переменную, которую вы полностью вернули, то другая сторона не узнает это изменение, потому что вы создаете новую переменную. это не имеет никакого отношения к угловому, его javascript. , если вы замените переменную INSIDE объекта, которую вы вернули, то другая сторона может распознать эти изменения, и в зависимости от обстоятельств угловой признает это автоматически и обновляет представления (не всегда, однако, это зависит от кода) –

1

Это потому, что всякий раз, когда вы возвращаете объект из функции в Javascript, вы фактически возвращаете ссылку на объект. В вашем примере

this.getObject = function(){ 
    return output; 
}; 

Возврат ссылки на object. И любые изменения, внесенные в эту ссылку, будут отражены в фактическом объекте, и поэтому для этого работает привязка данных.

Принимая во внимание, что при возврате строки из функции вы возвращаете значение, а не ссылку на фактическую строку.

this.getVal = function(){ 
    return output.string; 
}; 

Здесь вы возвращаете строку при возврате output.string, который имеет значение "init". Любая модификация, сделанная для object.string, больше не будет изменять возвращаемую строку, и поэтому она не подходит для привязки данных для value.

Для получения дополнительной информации см. this answer.

+0

Пожалуйста, пересмотреть свой ответ и возьмите мою ссылку «другой Plunker». Там вы видите, что объекты и строки ведут себя одинаково - они оба теряют ссылку, когда вы переназначаете их. –

+0

@HW, Извините, я дал неверную ссылку. Я исправил ссылку в своем ответе. См. Пример 4 в этом ответе, вы увидите, как переписывание объекта внутри функции теряет свою фактическую ссылку. – hallucinations

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