web-dev-qa-db-ja.com

AngularJsのディレクティブ内からスコープを変更する方法

ディレクティブ内のコールバック内からルートスコープ属性を変更する必要があります。ただし、ディレクティブはswitchディレクティブによって作成された内部スコープ内にあります。

HTML

<div ng-app="app" ng-controller='AppController'>
    <p>Selected: {{ selected }}</p>
    <div ng-switch on="selected">
        <div ng-switch-default>
            <p>Item: {{ selected }}</p>
            <custom-tag selected-item="selected" />
        </div>
        <div ng-switch-when="New value">
            <p>Worked</p>
        </div>
    </div>
</div>

JavaScript

angular.module('app', [])    
    .directive("customTag", [function () {
    return {
        restrict: "E",
        replace: true,
        template: "<input type='button' value='Click me' />",

        link: function (scope, element, attrs) {
            element.bind('click', function () {
                scope[attrs.selectedItem] = "New value";
                scope.$apply();
            });
        }
    };
}]);

function AppController($scope) {
    $scope.selected = 'Old value';
}

フィドル: http://jsfiddle.net/nJ7FQ/

私の目的は、選択領域に「新しい値」を表示できるようにすることです。私がやろうとしていることをどのように達成できますか?私は何を間違えていますか?

また、コンポーネントを作成しようとしているので。同じことを行う方法はありますか?

26
Fernando

私はフィドルを更新し、基本的に正しい「選択された」変数を取得するために親に行かなければならず、また分離されたスコープ=を使用して、渡された値と内部モデル間の双方向バインディングを取得しました。

http://jsfiddle.net/nJ7FQ/2/

angular.module('app', [])

    .directive("customTag", [function () {
    return {
        restrict: "E",
        replace: true,
        template: "<input type='button' value='Click me' />",
        scope: {model:'='},

        link: function (scope, element, attrs) {
            element.bind('click', function () {
                scope.model[attrs.selectedItem] = "New value";
                scope.$apply();
            });
        }
    };
}]);

function AppController($scope) {
    $scope.selected = 'Old value';
}

およびHTML

<div ng-app="app" ng-controller='AppController'>
    <p>Selected: {{ selected }}</p>
    <div ng-switch on="selected">
        <div ng-switch-default>
            <p>Item: {{ selected }}</p>
            <custom-tag selected-item="selected" model="$parent" />
        </div>
        <div ng-switch-when="New value">
            <p>Worked</p>
        </div>
    </div>
</div>

属性からプロパティの元の読み取り値を使用するようにフィドルを更新しました: http://jsfiddle.net/nJ7FQ/4/

20
shaunhusain

Jsfiddleを少し改善しました。

_angular.module('app', [])

    .directive("customTag", ['$parse', function ($parse) {
    return {
        restrict: "E",
        replace: true,
        template: "<input type='button' value='Click me' />",

        link: function (scope, element, attrs) {
            element.bind('click', function () {
                scope.$apply(function () {
                    $parse(attrs.selectedItem).assign(scope.$parent, "New value");
                });
            });
        }
    };
}]);

function AppController($scope) {
    $scope.selected = { 'foo': 'Old value' };
}
_

http://jsfiddle.net/nJ7FQ/15/

このように、変更するスコープ値は、例の_selected.foo_のようなオブジェクトプロパティにすることもできます。また、scopeパラメーターを削除し、常に親スコープを使用するようにディレクティブに指示しました。最後に、クリックハンドラーを_$apply_コールバックにラップしました(たとえば、 here を参照)。もちろん、element.bind()の代わりにngClickを使用する方が良いでしょう。

15
stofl