2016-04-28 3 views
0

В настоящее время я изучаю AngularJS.Обновление ng-repeat при изменении данных

Я застреваю, пытаясь обновить ряд кнопок, которые я создал из директивы, когда данные объекта обновляются.

Я прочитал несколько сообщений, посвященных аналогичным проблемам, где данные, не созданные в директиве, не будут обновляться безрезультатно.

HTML

<body> 
    <div id="application" data-ng-app="ApplicationDirective" ng-controller="ApplicationController" class="container-fluid"> 
     <side-panel class="col-lg-2"></side-panel> 
     <div ng-controller="HomeController" class="content col-lg-10"> 

     </div> 
    </div> 
</body> 

Как вы можете видеть, что я определил 2 контроллера. 1 ApplicaitonControler для управления приложением в целом, а затем вторым HomeController для управления внутренней секцией HMTL.

У меня тогда есть директива, которая генерирует ряд кнопок для боковой панели.

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

app.directive("sidePanel", function() { 
    return { 
     restrict: "E", 
     template : "<div>" + 
        "<input ng-repeat='btn in sidePanelButtons' type='button' value={{btn.value}}>" +    
        "</div>" 
    }; 
}); 

В $scope данные выше определяется в ApplicationContoller. Затем я обновляю данные в HomeController.

app.controller("HomeController", function($scope) { 
    $scope.sidePanelButtons = $scope.sidePanelButtons.concat([ 
     {value:"TEST"} 
    ]); 
}); 

На данный момент, если я вхожу в sidePanelButtons вар, то я могу видеть, что данные были успешно добавлены, однако ничего в изменениях HTML ?.

Я попытался использовать метод $ scope. $ Apply, но получаю error.

Потенциально у меня неправильные методологии дизайна, поэтому любая помощь будет оценена по достоинству.

+0

Как быстрый совет: вместо этого попробуйте '$ timeout'. Он автоматически выполняет '$ scope. $ Apply'. – Beat

ответ

2

Метод concat() возвращает новый массив.

Так что, когда вы делаете

$scope.sidePanelButtons = $scope.sidePanelButtons.concat([ 
    {value:"TEST"} 
]); 

Вы создаете новый sidePanelButtons собственность в рамках HomeController, разбивая ссылку на sidePanelButtons массив в ApplicationController области. В директиве вашей боковой панели отображается ApplicationController область действия, которая остается неизменной.

Вместо этого $scope.sidePanelButtons.push().

+0

Ahhhhhh интересно, это имеет большой смысл, я проверю это как можно скорее. – Zze

+0

Так что я просто проверил это, и это сработало, однако теперь у меня есть 3 оригинальные кнопки и одна пустая кнопка, хотя я пытался вставить в объект 2 новых значения.? '$ Scope.sidePanelButtons.push ([ \t \t {значение: "TEST1"}, \t \t {значение: "TEST2"} \t]);' – Zze

+0

@Zze Я не знаю, что ваш 'нг-повтор 'iterates on, но в идеале вы должны нажимать такие объекты, как' $ scope.sidePanelButtons.push ({значение: "TEST1"}, {значение: "TEST2"}); 'а не массив объектов. –

0

Попробуйте

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

 
app.directive("sidePanel", function() { 
 
    return { 
 
     restrict: "E", 
 
     scope: { 
 
     \t buttons: '=' 
 
     }, 
 
     template : "<div>" + 
 
        "<input ng-repeat='btn in buttons' type='button' value={{btn.value}}>" +    
 
        "</div>" 
 
    }; 
 
}); 
 

 
app.controller("ApplicationController", function($scope) { 
 
\t \t $scope.sidePanelButtons = [ 
 
     {value:"TEST"} 
 
    ]; 
 
});

0

Вы не можете обновить $ объем одного контроллера от другого контроллера. $ scope является локальным для каждого контроллера, поэтому обновленное значение, отображаемое в журнале, принадлежит HomeController, а не ApllicationController. Либо вы определяете и обновляете свои данные в одном контроллере, либо используете сервис, если вам действительно нужен доступ к одному набору данных с двух контроллеров.

Другой способ - использовать $ rootScope вместо $ scope, чтобы сделать его доступным для всех контроллеров.

app.controller("HomeController", function($scope, $rootScope) { 
$rootScope.sidePanelButtons = $rootScope.sidePanelButtons.concat([ 
    {value:"TEST"} 
]); 
}); 

app.controller("ApplicationContoller", function($scope, $rootScope) { 
$rootScope.sidePanelButtons = //define here; 
}); 

Но я думаю, что есть еще одна проблема с вашей директивой.Чтобы получить доступ к переменным типа sidePanelButtons, вам нужно получить доступ к своей переменной $ scope из вашей директивы. Для решения этой проблемы см.: Access controller scope from directive

+0

Это неправда. Области дочерних объектов прототипно унаследованы от их родительской области, поэтому они могут обновлять свойства объекта в родительской области. –

+0

Когда Angular оценивает {{variable}}, сначала он просматривает область, связанную с данным элементом, для свойства name. Если такого свойства не найдено, он ищет родительскую область и так далее до тех пор, пока не будет достигнута область корня. В JavaScript это поведение известно как прототипическое наследование, а дочерние области прототипически наследуются от своих родителей. Но здесь это не так. Когда внутри контроллера, $ scope относится к локальной копии. Если контроллеры вложены, то запись $ scope. $ Parent.sidePanelButtons позволит дочернему контроллеру получить доступ к родительскому контроллеру $ scope.sidePanelButton –

+0

* «Но здесь это не так» * - почему? Это так. * «Если контроллеры вложены, то запись $ scope. $ Parent.sidePanelButtons позволит дочернему контроллеру получить доступ к родительскому контроллеру $ scope.sidePanelButton *." Конечно. Но это совершенно необязательно здесь. –

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