1

У меня есть массив элементов, где каждый элемент привязан к директиве. Когда массив сначала построен, все хорошо, но когда я возвращаю массив новым значениям, функции ссылок для директив не срабатывают. Вот HTML, где каждый элемент массива кадра содержит ряд элементов, каждый из которых связан с моей директивы, прохладного диаграммыУгловая связь не срабатывает при изменении данных

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

 

 
app.controller("controller", function($scope) { 
 
$scope.frames = [] 
 
    $scope.getData = function() { 
 
    var frames = ["adsf","qwerty"]; 
 
    alert("got new Data") 
 
     
 
    $scope.frames.push(frames) 
 
    
 
    } 
 
    
 
}); 
 

 
app.directive('coolChart', function() { 
 
    return { 
 
    restrict: 'E', 
 
    scope: { 
 
     data: '=data' 
 
    }, 
 
    link: function(scope, element) { 
 
     data = data.toUpperCase(); 
 
     alert("Link called with: " + data) 
 
    } 
 
    } 
 
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script> 
 

 
<body ng-app="theapp"> 
 
    <div ng-controller="controller"> 
 
    {{frames}}asdf 
 
    <button ng-click="getData()">run get Data</button> 
 
    <div class="outer-frame" ng-repeat="frame in frames track by $index"> 
 
     {{frame}} 
 
     <div class="chart-container" ng-repeat="item in frame track by $index"> 
 
     {{item}} 
 
     <cool-chart data="item"></cool-chart> 
 
     </div> 
 
    </div> 
 
    </div> 
 
</body>

Вы заметите, что вы видите alert "получил новые данные", но функция директивной ссылки не вызывается.

Я думаю об этом неправильно? Какая здесь правильная структура для замены содержимого массива, чтобы данные, привязанные к каждому элементу массива, запускали правильные уведомления об изменениях?

+0

Функция ссылку вызывается, однако функция ссылка должна ссылаться на «scope.data», а не только данные. Мой ответ ниже имеет рабочее решение. – Urielzen

ответ

0

Постарайся не нарушая ссылки на начальные кадры массива, когда вы переназначить его ... вместо того, чтобы попытаться его опорожнение и объединить новые данные в него так ссылка не потеряли

// declare empty array on scope 
$scope.frames = []; 
var getData = function() { 
    // reset scope array 
    $scope.frames.length = 0; 
    // merge data into frames 
    $scope.frames.concat(data); // not sure where data comes from 
}; 

В качестве альтернативы, если данные были приведены в от события за пределами углового вы должны были бы сказать, угловатый, чтобы запустить переваривать с $ применить()

Я вынул петлю while, потому что я не понимаю, почему это было необходимо

+0

это не сработает, потому что concat не изменяет «это», но в духе вашего сообщения я установил длину $ scope.frames в 0, а затем нажал туда ... не повезло. Я пробовал обманывать с помощью $ apply, но я не совсем понимаю, где ... когда я попытался назвать это в этом контексте, у меня всегда появляется ошибка, говорящая, что $ digest уже выполняется. Для чего это стоит, также попробовал $ timeout, но даже если я вижу, что массив опустел, когда данные заселены, директива не сообщается. Цикл while является тангенциальным для обсуждения, но необходим в том, что он группирует элементы в фреймы. –

+0

Мне никогда не нужно делать это в любом случае, я и угловые довольно хороши в новых ссылках ... Можете ли вы сделать демоверсию, которая реплицирует проблему? Когда данные обернуты в $ http, он будет называть $ apply, который, скорее всего, потому, что вы получаете дайджест в процессе ... было только предложение, если данные поступали извне угловыми – charlietfl

+0

проверить мои обновления на исходный вопрос (я использовал большую часть образец другого респондента). Я уверен, что об этом неправильно думаю, и что угловой не считает, что объекты изменились (т. Е. Он все еще использует объект, связанный с созданием исходного массива), но я не понимаю, как это сделать работать или как рыть дальше. –

0

Я сколотить фрагмент кода это напоминает большую часть вашего кода. И это работает, когда вы запускаете фрагмент. Если вы можете, отредактируйте свой вопрос аналогичным образом, чтобы попытаться решить проблему :)

Обновлено: теперь ссылка запускает предупреждение, как ожидалось.

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

 

 
app.controller("controller", function($scope) { 
 
    $scope.frames = [] 
 
    $scope.getData = function() { 
 
    var frames = ["adsf", "qwerty"]; 
 
    console.log("got new Data") 
 

 
    $scope.frames.push(frames) 
 

 
    } 
 

 
}); 
 

 
app.directive('coolChart', function() { 
 
    return { 
 
    restrict: 'E', 
 
    scope: { 
 
     data: '=data' 
 
    }, 
 
    link: function(scope, element) { 
 
     scope.data = scope.data.toUpperCase(); 
 
     alert("Link called with: " + scope.data) 
 
    } 
 
    } 
 
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script> 
 

 
<body ng-app="theapp"> 
 
    <div ng-controller="controller"> 
 
    {{frames}}asdf 
 
    <button ng-click="getData()">run get Data</button> 
 
    <div class="outer-frame" ng-repeat="frame in frames track by $index"> 
 
     {{frame}} 
 
     <div class="chart-container" ng-repeat="item in frame track by $index"> 
 
     {{item}} 
 
     <cool-chart data="item"></cool-chart> 
 
     </div> 
 
    </div> 
 
    </div> 
 
</body>

+0

Спасибо за пример - я принял его в своем вопросе. Заметили ли вы, что ваше оповещение в функции ссылки НЕ запускалось. Я добавил еще одно предупреждение, чтобы подтвердить пожары «полученных данных» (и в этом случае предупреждает об общем пожаре). Я также добавил, что toUpperCase является прокси-сервером для обработки данных (который в моем реальном коде восстанавливает диаграмму d3).Если мы можем «исправить» этот образец, чтобы применить верхний регистр, я думаю, что он будет переводиться и на мой код. –

+0

Ответ был обновлен, и теперь он должен запускать предупреждение, как ожидалось. Обратите внимание на информацию о области scope.data в Надеюсь, это поможет. – Urielzen

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