0

Изменения в моей переменной области foo обновляются в html. Когда это значение изменяется внутри области действия контроллера директивы, оно не обновляется в html.Угловые - изменения в области действия контроллера не отражены в поле зрения

Что нужно сделать, чтобы обновить его?

У меня есть простой example:

app.js

var app = angular.module('app', []); 

app.controller('ctrl', function($scope) { 
    $scope.foo = 99; 

    $scope.changeValue = function() { 
    $scope.foo = $scope.foo + 1; 
    } 
}); 

app.directive('d1', function(){ 
    return { 
    restrict: 'E', 
    scope: { 
     theFoo: '=' 
    }, 
    templateUrl: 'd1.html', 
    controller: 'd1Ctrl', 
    } 
}); 

app.controller('d1Ctrl', function($scope) { 
    $scope.test = $scope.theFoo; 
}); 

d1.html

<div> 
    <p>The value of foo is '{{theFoo}}'.</p> 
    <p>The value of test is '{{test}}'.</p> 
</div> 

внутри index.html

<d1 the-foo='foo'> 
</d1> 

<button ng-click='changeValue()'>change value</button> 

Таким образом, в целом, {{theFoo}} обновляется, но {{test}} нет. Зачем?

ответ

1

Причина заключается в том, что $scope.foo значение является примитивным.

В контроллере директивы вы назначаете $scope.test один раз, когда контроллер инициализируется. Примитивы не имеют наследования, так как объекты не имеют ничего, что могло бы изменить $scope.test после этого начального назначения

Если вы использовали объект вместо этого, чтобы передать ... наследование будет действовать, и вы увидите изменения ... иначе вы должны были бы смотреть $scope.theFoo и делать обновления $scope.test себя

+0

Это одна из проблем, которые у меня есть с угловыми.Хотя использование * controller-as *, похоже, позволяет избежать большинства из этих головных болей, потому что он рассматривается как не-примитивный, мне все еще не нравится, как нам нужно переосмыслить наши пути обновления примитивных значений. – jusopi

+0

@jusopi вся проблема исчезает, если вы следуете лучшие практики и использование объектов вместо примитивов. Я редко использую $ watch в своем коде и удостоверяюсь, что я использую свойства объекта, а не примитивы – charlietfl

+0

извините, но сказать, что вся проблема исчезает, неверна. Если он не изменит внутреннюю работу директивы, чтобы вытащить тестовое значение из не-примитивного связанного значения, 'test' все еще не обновляется. http://plnkr.co/edit/bRrQ9z4oBYrdBCLwbOjP?p=preview – jusopi

1

Код, который у вас есть в вашем контроллере, инициализируется только этим значением, если он действительно установлен во время соединения контроллера. Любые последующие изменения не будут работать.

Если вы хотите связать любые последующие изменения, вам необходимо установить оператор $ watch в контроллере или в функции ссылки.

$scope.$watch('theFoo', function(val){ $scope.test = val; }) 

обновленный plunker - http://plnkr.co/edit/eWoPutIJrwxZj9XJu6QG?p=preview

0

здесь вы выделили область применения директивы, так test не видно d1.html, если вам нужно изменить test вместе с theFoo вы должны сначала сделать его видны директиве

app.directive('d1', function(){ 
    return { 
    restrict: 'E', 
    scope: { 
     theFoo: '=', 
     test : '=' //getting test as well 
    }, 
    templateUrl: 'd1.html', 
    controller: 'd1Ctrl', 
    } 
}); 

и в index.html вы должны передать значение для испытания на <d1 the-foo='foo' test='foo'></d1>

в коде выше ваш контроллер не так много пользы, код будет работать хорошо, даже без этой части controller: 'd1Ctrl'. с этим примером вам не нужно использовать $watch.

+0

Это упрощенный пример для демонстрации моей проблемы - 'test' определен в области контроллера директивы - поэтому он должен быть видимым. Плюс он получает значение изначально, но он не обновляется. – PeteGO