Uwaga: aktualizuję tę odpowiedź, ponieważ znajduję lepsze rozwiązania. Zachowuję również stare odpowiedzi do wykorzystania w przyszłości, o ile będą one powiązane. Najnowsza i najlepsza odpowiedź jest najważniejsza.
Lepsza odpowiedź:
Dyrektywy w angularjs są bardzo potężne, ale potrzeba czasu, aby zrozumieć, które procesy za nimi stoją.
Podczas tworzenia dyrektyw angularjs umożliwia utworzenie izolowanego zakresu z pewnymi powiązaniami z zakresem nadrzędnym. Te powiązania są określone przez atrybut, który dołączasz do elementu w DOM oraz sposób definiowania właściwości scope w obiekcie definicji dyrektywy .
Istnieją 3 rodzaje opcji wiązania, które możesz zdefiniować w zakresie i zapisujesz je jako atrybuty związane z prefiksami.
angular.module("myApp", []).directive("myDirective", function () {
return {
restrict: "A",
scope: {
text: "@myText",
twoWayBind: "=myTwoWayBind",
oneWayBind: "&myOneWayBind"
}
};
}).controller("myController", function ($scope) {
$scope.foo = {name: "Umur"};
$scope.bar = "qwe";
});
HTML
<div ng-controller="myController">
<div my-directive my-text="hello {{ bar }}" my-two-way-bind="foo" my-one-way-bind="bar">
</div>
</div>
W takim przypadku w zakresie dyrektywy (niezależnie od tego, czy chodzi o połączenie funkcji czy kontrolera), możemy uzyskać dostęp do tych właściwości w następujący sposób:
/* Directive scope */
in: $scope.text
out: "hello qwe"
// this would automatically update the changes of value in digest
// this is always string as dom attributes values are always strings
in: $scope.twoWayBind
out: {name:"Umur"}
// this would automatically update the changes of value in digest
// changes in this will be reflected in parent scope
// in directive's scope
in: $scope.twoWayBind.name = "John"
//in parent scope
in: $scope.foo.name
out: "John"
in: $scope.oneWayBind() // notice the function call, this binding is read only
out: "qwe"
// any changes here will not reflect in parent, as this only a getter .
„Nadal OK” Odpowiedź:
Ponieważ ta odpowiedź została zaakceptowana, ale ma pewne problemy, zamierzam ją zaktualizować do lepszej. Najwyraźniej $parse
jest to usługa, która nie leży we właściwościach bieżącego zakresu, co oznacza, że przyjmuje tylko wyrażenia kątowe i nie może osiągnąć zakresu.
{{
, }}
wyrażenia są kompilowane podczas inicjacji angularjs, co oznacza, że kiedy próbujemy uzyskać do nich dostęp w naszej postlink
metodzie dyrektyw , są one już skompilowane. ( {{1+1}}
jest 2
już w dyrektywie).
Oto jak chcesz użyć:
var myApp = angular.module('myApp',[]);
myApp.directive('myDirective', function ($parse) {
return function (scope, element, attr) {
element.val("value=" + $parse(attr.myDirective)(scope));
};
});
function MyCtrl($scope) {
$scope.aaa = 3432;
}
.
<div ng-controller="MyCtrl">
<input my-directive="123">
<input my-directive="1+1">
<input my-directive="'1+1'">
<input my-directive="aaa">
</div>
Jedną z rzeczy, które powinieneś tutaj zauważyć, jest to, że jeśli chcesz ustawić ciąg wartości, powinieneś zawinąć go w cudzysłów. (Patrz 3. wejście)
Oto skrzypce do zabawy: http://jsfiddle.net/neuTA/6/
Stara odpowiedź:
Nie usuwam tego dla ludzi, którzy mogą być wprowadzani w błąd, tak jak ja, zauważ, że używanie $eval
jest w porządku poprawny sposób, ale $parse
ma inne zachowanie, prawdopodobnie nie będziesz tego potrzebował w większości przypadków.
Sposobem na to jest ponowne użycie scope.$eval
. Nie tylko kompiluje wyrażenie kątowe, ale ma również dostęp do właściwości bieżącego zakresu.
var myApp = angular.module('myApp',[]);
myApp.directive('myDirective', function () {
return function (scope, element, attr) {
element.val("value = "+ scope.$eval(attr.value));
}
});
function MyCtrl($scope) {
}
Brakowało ci tego $eval
.
http://docs.angularjs.org/api/ng.$rootScope.Scope#$eval
Wykonuje wyrażenie w bieżącym zakresie zwracając wynik. Wszelkie wyjątki w wyrażeniu są propagowane (nieprzechwycone). Jest to przydatne podczas oceny wyrażeń kątowych.