0

コレクションを取り込んでドロップダウンを作成するディレクティブがあります。

.directive("lookupdropdown", function () {
    return {
        restrict: 'E',
        scope: {
            collectionset: '=',
            collectionchoice: '='
        },
        replace: true,
        template: '<select class="input-large" ui-select2 ng-model="collectionchoice" data-placeholder="">' +
                    '    <option ng-repeat="collection in repeatedCollection" value="{{collection.id}}">{{collection.description}}</option>' +
                    '</select>',
        controller: ["$scope", function ($scope) {
            $scope.repeatedCollection = new Array(); //declare our ng-repeat for the template
            $scope.$watch('collectionset', function () {
                if ($scope.collectionset.length > 0) {
                    angular.forEach($scope.collectionset, function (value, key) { //need to 'copy' these objects to our repeated collection array so we can template it out
                        $scope.repeatedCollection.push({ id: value[Object.keys(value)[0]], description: value[Object.keys(value)[1]] });
                    });
                }
            });

            $scope.$watch('collectionchoice', function (newValue, oldValue) {
                debugger;
                $scope.collectionchoice;
            });
        } ]
    }
});

これはうまくいきます。ドロップダウンを問題なく構築します。ドロップダウン値を変更すると、2 番目のウォッチ関数が呼び出され、コレクション選択の値が必要な値に設定されていることがわかります。ただし、ディレクティブに入れた collectionchoice は、新しい選択にバインドされません。

<lookupDropdown collectionset="SecurityLevels" collectionchoice="AddedSecurityLevel"></lookupDropdown>

それが HTML マークアップです。

これはJavaScriptです:

$scope.SecurityLevels = new Array();
$scope.GetSecurityLevelData = function () {
    genericResource.setupResource('/SecurityLevel/:action/:id', { action: "@action", id: "@id" });
    genericResource.getResourecsList({ action: "GetAllSecurityLevels" }).then(function (data) {
        $scope.AddedSecurityLevel = data[0].SCRTY_LVL_CD;
        $scope.SecurityLevels = data;
        //have to get security levels first, then we can manipulate the rest of the page
        genericResource.setupResource('/UserRole/:action/:id', { action: "@action", id: "@id" });
        $scope.GetUserRoles(1, "");
    });
}
$scope.GetSecurityLevelData();

次に、新しいユーザー ロールを投稿するときに、ユーザー ロール フィールドを次のように設定します。

 NewUserRole.SCRTY_LVL_CD = $scope.AddedSecurityLevel;

しかし、ドロップダウンを更新したにもかかわらず、これは最初の項目のままであり、ウォッチ機能に従って正しい値に変更されました。ここで何が欠けていますか?

4

2 に答える 2

1

この問題に直面したのは、Javascript の典型的な性質の継承が原因でした。説明してみましょう。Javascript ではすべてがオブジェクトであり、一度オブジェクトを作成すると、すべての Object.Prototype(s) を継承し、最終的に最終的なオブジェクト、つまり Object につながります。そのため、JavaScript のすべてのオブジェクト (関数も含む) を .toString() できるのは、それらがすべて Object から継承されているためです。

ディレクティブに関するこの特定の問題は、Angular JS の $scope の誤解が原因で発生します。$scope はモデルではありませんが、モデルのコンテナーです。$scope でモデルを定義する正しい方法と間違った方法については、以下を参照してください。

...
$scope.Username = "khan@gmail.com"; //Incorrect approach
$scope.Password = "thisisapassword";//Incorrect approach
...
$scope.Credentials = {
    Username: "khan@gmail.com", //Correct approach
    Password: "thisisapassword" //Correct approach
}
...

2 つの宣言は大きな違いを生みます。ディレクティブがそのスコープ (ディレクティブの分離されたスコープ) を更新すると、実際には、親スコープへの実際の参照を更新するのではなく、参照を新しい値で完全にオーバーライドしたため、ディレクティブとコントローラーのスコープが切断されました。

あなたのアプローチは次のとおりです。

<lookupDropdown collectionset="SecurityLevels" collectionchoice="$parent.AddedSecurityLevel"></lookupDropdown>

このアプローチの問題は、機能しますが、推奨される解決策ではないことです。その理由は次のとおりです。ディレクティブが、ディレクティブのスコープと実際のコントローラーの間の別の分離されたスコープを持つ別のディレクティブ内に配置されている場合はどうなるでしょうか。その場合、やらなければならず$parent.$parent.AddedSecurityLevel、これは永遠に続く可能性があります。したがって、推奨される解決策ではありません。

結論:

スコープにモデルを定義するオブジェクトがあることを常に確認し、分離スコープを使用するか、分離スコープを使用する ng ディレクティブを使用するときは常に、ng-modelどこかにドット (.) があるかどうかを確認します。欠落している場合は、あなたはおそらく間違ったことをしています。

于 2014-05-25T18:56:10.020 に答える
0

ここでの問題は、私のディレクティブが別のディレクティブに変換されていたことです。スコープを作成して、それが含まれていたディレクティブの子を渡します。つまり、$parent -> $child -> $child のようなものです。もちろん、これは第 3 層と第 2 層に変更を加えていました。しかし、最初のレイヤーは何が起こっているのかわかりませんでした。これで修正されました:

<lookupDropdown collectionset="SecurityLevels" collectionchoice="$parent.AddedSecurityLevel"></lookupDropdown>
于 2013-09-10T20:56:40.870 に答える