Idea dyrektywy związanej z databindingiem jest interesująca, ale nie jest to sposób, w jaki bym to zrobił, ponieważ uważam, że napotkasz problemy z priorytetami dyrektywy, a także fakt, że jest to bardzo niestandardowe i sprawiłoby, że twój kod byłby trudny do naśladowania. dla przyszłych programistów. Jest na to kilka sposobów, dlatego omówię 3 różne rozwiązania, z których korzystałem.
Rozwiązanie 1
Jeśli trzeba tylko jeden sposób powiązania danych, najprostszym rozwiązaniem jest użycie zakres kątowy jest. $ Eval funkcja na ciąg znaków obiektu wewnątrz swojej dyrektywy po interpolacji żadnych prostych zmiennych zakres języka na używając {{}}. Reprezentacja łańcuchowa nie musi być poprawna JSON, ponieważ zauważysz w poniższym przykładzie, że nie umieszczam cudzysłowów wokół kluczy obiektów.
w widoku:
<div databinding="{one:'first', two:{{scopeVar}}, complex:[1,2, "Hi"]}"></div>
A w JavaScript:
app.directive('databinding', function() {
return{
link: function (scope, elm, attrs) {
console.debug(scope.$eval(attrs['databinding']));
}
}
});
roztworu 2
Innym rozwiązaniem wiąże jednokierunkowe danych do utworzenia obiektu funkcji Wewnątrz kontroler i przekazać go do dyrektywy za pomocą "@" (lub nawet "="):
W regulatorze:
$scope.options = {one: "first, two: "second"};
W widoku:
<div databinding="options"></div>
A w javascript:
app.directive('databinding', function() {
return{
scope: {
options: "@" //Can also use = here
},
link: function (scope, elm, attrs) {
console.log(scope.options);
}
}
});
Rozwiązanie 3
Jeśli potrzebują dwukierunkowy powiązanie danych, w większości jesteś poza szczęście, ponieważ nie ma eleganckiego sposobu na zrobienie tego. JEDNAKŻE, jeśli jesteś na rynku rozwiązań hackish, możesz osiągnąć dwukierunkowe powiązanie danych z metodą bardzo podobną do rozwiązania 2, ale ze zmianą w obiekcie opcji.
Zamiast zadeklarować obiekt opcji zawierający proste typy danych pierwotnych, takie jak łańcuchy, utwórz obiekt obojętny wewnątrz obiektu opcji, który następnie zadeklarujesz w swoim zmiennym. Robiąc to w ten sposób, zmiany w zmiennych zakresu w kontrolerze będą również realizowane w ramach dyrektywy, co zostało zademonstrowane w ramach limitów czasu.
Kontroler:
$scope.someScopeVar = "Declared in controller"
$scope.options = {
dummy: {
one: $scope.someScopeVar,
two: "second"
}
}
window.setTimeout(function(){
$scope.someScopeVar = "Changed in controller";
}, 2000)
Widok:
<div databinding="options"></div>
dyrektywa:
app.directive('databinding', function() {
return{
scope: {
options: "=" //You need to use = with this solution
},
link: function (scope, elm, attrs) {
console.log(scope.options.dummy.one); //Outputs "Declared in controller"
window.setTimeout(function(){
console.log(scope.options.dummy.one) //Outputs "Changed in controller"
}, 5000)
}
}
});
Ta metoda działa od obiektów javascript przechodzi przez odniesienie natomiast prymitywy są kopiowane. Poprzez zagnieżdżenie obiektu w obiekcie powiązanie danych zostaje zachowane.
To zadziała, jeśli zmienię atrybut na inny. Próbuję tego uniknąć. Chcę wysłać wszystkie moje databindings na jednym atrybucie, a następnie rozdzielić je. Może ponownie przeczytaj pytanie, aby wyjaśnić. – Spencer