1. ホーム
  2. javascript

[解決済み] カスタムディレクティブの中で評価された属性を取得する方法

2022-03-15 22:43:54

質問

を取得しようとしています。 評価済み 属性を使用することができますが、正しい方法を見つけることができません。

私が作成した このjsFiddle を詳しく説明します。

<div ng-controller="MyCtrl">
    <input my-directive value="123">
    <input my-directive value="{{1+1}}">
</div>

myApp.directive('myDirective', function () {
    return function (scope, element, attr) {
        element.val("value = "+attr.value);
    }
});

何が足りないのか?

解決方法は?

お知らせ 私はより良い解決策を見つけると、この答えを更新します。また、関連性がある限り、将来の参考のために古い回答も保存しています。最新かつ最良の回答が優先されます。

ベターアンサー

angularjsのディレクティブは非常に強力ですが、その背後にあるプロセスを理解するのに時間がかかります。

ディレクティブを作成している間、angularjsでは 分離されたスコープ に、親スコープへのバインディングをいくつか追加しました。これらのバインディングは 属性 DOMで要素をアタッチする方法、および スコープ プロパティに ディレクティブ定義オブジェクト .

スコープで定義できるバインディングオプションは3種類あり、それらをプレフィクス関連属性として記述します。

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>

その場合、ディレクティブのスコープでは (リンク関数でもコントローラでも)、以下のようにこれらのプロパティにアクセスすることができます。

/* 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 .

"まだ大丈夫"回答。

この回答は受理されましたが、いくつかの問題があるので、より良いものに更新するつもりです。どうやら $parse は現在のスコープのプロパティに属さないサービスです。つまり、angular 式を受け取るだけで、スコープに到達することはできません。 {{ , }} 式は、angularjs の起動中にコンパイルされるため、ディレクティブでそれらにアクセスしようとすると postlink メソッドを呼び出すと、それらはすでにコンパイルされています。( {{1+1}}2 ディレクティブの中にすでにある)。

このように使いたいものです。

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>​​​​​​​​

ここで一つ注意しなければならないのは、値の文字列を設定したい場合は、引用符で囲む必要があるということです。(3番目の入力参照)

ここで、フィドルを使って遊んでみましょう。 http://jsfiddle.net/neuTA/6/

古い回答です。

私のように誤解されやすい人のために削除するわけではありません。 $eval は正しい方法で全く問題ありませんが $parse は動作が異なるので、おそらくほとんどの場合、これを使う必要はないでしょう。

その方法は、またしても scope.$eval . angular式をコンパイルするだけでなく、現在のスコープのプロパティにアクセスすることができます。

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

myApp.directive('myDirective', function () {
    return function (scope, element, attr) {
        element.val("value = "+ scope.$eval(attr.value));
    }
});

function MyCtrl($scope) {
   
}​

不足しているのは $eval .

http://docs.angularjs.org/api/ng.$rootScope.Scope#$eval

現在のスコープで式を実行し、結果を返します。式の中の例外はすべて伝搬される(捕捉されない)。これは、angular式を評価するときに便利です。