2016-04-28 10 views
0

Ich lerne gerade AngularJS.Aktualisierung ng-repeat bei Datenänderung

Ich bin fest, versucht zu aktualisieren eine Reihe von Schaltflächen, die ich von einer Direktive generiert habe, wenn die Objektdaten aktualisiert werden.

Ich habe eine Reihe von Beiträgen gelesen, die ähnliche Probleme behandeln, bei denen Daten, die nicht in einer Direktive erstellt werden, nicht vergeblich aktualisiert werden.

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> 

Wie Sie habe ich 2 Controller definiert sehen können. 1 ApplicaitonControler, um die Anwendung als Ganzes zu verwalten und dann eine zweite HomeController, um einen inneren Abschnitt der HMTL zu verwalten.

Ich habe dann eine Direktive, die eine Reihe von Tasten für eine Seitenwand erzeugt.

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 Die Daten für die oben in der ApplicationContoller definiert. Dann aktualisiere ich die Daten in HomeController.

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

An diesem Punkt, wenn ich die sidePanelButtons var log dann kann ich sehen, dass die Daten erfolgreich angehängt wurde, aber nichts in den HTML-Änderungen ?.

Ich habe versucht, mit $ Scope. $ Apply-Methode, aber ich bekomme eine error.

Möglicherweise habe ich die falsche Design-Methoden, so dass jede Hilfe geschätzt werden würde.

+0

Als einen kurzen Hinweis: Versuchen Sie stattdessen eine '$ Timeout '. Es wird automatisch ein '$ scope. $ Apply' ausgeführt. – Beat

Antwort

2

Die Methode concat() gibt ein neues Array zurück. So

wenn Sie das tun

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

Sie eine neue sidePanelButtons Eigenschaft in Homecontroller Rahmen zu schaffen, brechen Sie den Verweis auf sidePanelButtons Array in ApplicationController Umfang. Ihre Side-Panel-Richtlinie überwacht ApplicationController Scope, die unverändert bleiben.

Do $scope.sidePanelButtons.push() stattdessen.

+0

Ahhhhhh interessant, das macht sehr viel Sinn, ich werde das so schnell wie möglich testen. – Zze

+0

Also habe ich das gerade getestet und es hat irgendwie funktioniert, aber jetzt habe ich die 3 originalen Tasten und eine einzelne leere Taste, obwohl ich versucht habe, 2 neue Werte in das Objekt zu schieben ..? '$ Scope.sidePanelButtons.push ([ \t \t {Wert: "TEST1"}, \t \t {Wert: "TEST2"} \t]);' – Zze

+0

@Zze Ich weiß nicht, was Ihr 'ng-repeat 'iteriert weiter, aber im Idealfall sollten Sie Objekte wie' $ scope.sidePanelButtons.push ({value: "TEST1"}, {value: "TEST2"}); 'anstelle von Arrays von Objekten drücken. –

0

Versuchen Sie, diesen

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

Sie nicht den $ Umfang von einer Steuerung von einem anderen Controller aktualisieren. $ scope ist für jeden Controller lokal, daher gehört der im Protokoll angezeigte aktualisierte Wert zu HomeController und nicht zu ApllicationController. Entweder Sie definieren und aktualisieren Ihre Daten in demselben Controller oder verwenden einen Service, wenn Sie wirklich auf den gleichen Datensatz von zwei Controllern zugreifen müssen.

Eine andere Möglichkeit ist die Verwendung von $ rootScope anstelle von $ scope, um es in allen Controllern verfügbar zu machen.

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

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

Aber ich denke, es gibt ein anderes Problem mit Ihrer Richtlinie.Sie müssen auf Ihren Controller $ scope von Ihrer Anweisung aus zugreifen, um auf die Variablen wie sidePanelButtons zuzugreifen. Zur Lösung dieses Problems finden Sie unter: Access controller scope from directive

+0

Dies ist nicht wahr. Untergeordnete Bereiche werden prototypisch vom übergeordneten Bereich übernommen, sodass sie die Objekteigenschaften im übergeordneten Bereich aktualisieren können. –

+0

Wenn Angular {{variable}} auswertet, wird zunächst der mit dem angegebenen Element für die name -Eigenschaft verknüpfte Bereich betrachtet. Wenn keine solche Eigenschaft gefunden wird, wird der übergeordnete Bereich usw. durchsucht, bis der Root-Bereich erreicht ist. In JavaScript wird dieses Verhalten als prototypische Vererbung bezeichnet, und untergeordnete Bereiche erben prototypisch von ihren übergeordneten Elementen. Aber das ist hier nicht der Fall. Innerhalb eines Controllers bezieht sich $ scope auf die lokale Kopie. Wenn die Controller verschachtelt sind, schreibt $ scope. $ Parent.sidePanelButtons würde dem Kind-Controller erlauben, auf den übergeordneten Controller zuzugreifen $ scope.sidePanelButton –

+0

* "Aber das ist hier nicht der Fall" * - warum? Das ist hier der Fall. * "Wenn die Controller verschachtelt sind und dann $ scope geschrieben wird. $ Parent.sidePanelButtons würde dem Kind-Controller erlauben, auf den übergeordneten Controller $ scope.sidePanelButton * zuzugreifen." Natürlich. Aber das ist hier völlig unnötig. –

Verwandte Themen