2

選択した HTML と機能を一元化するディレクティブがありますが、ng-change が発生した後に ng-model が更新されるという問題があります。

以下は、焦点を絞った jsfiddle の例です。

http://jsfiddle.net/U3pVM/1568/

(SOがそうでなければ文句を言うのでコード)

HTML:

<div ng-app="myApp">    
    <div ng-controller="MainCtrl">
        <p>fooId is currently : {{fooId}}</p>

        <app-drop-down model="fooId" options="fooOptions" opt-value="id" opt-label="label" on-change="dropDownChanged"></app-drop-down>
    </div>
</div>

JS:

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

app.controller('MainCtrl', function ($scope, $log) {
    $scope.fooId = -1;

    $scope.fooOptions = [{
        id: 1,
        label: "A"
    }, {
        id: 2,
        label: "B"
    }];

    $scope.dropDownChanged = function (id) {
        $log.info('changed : ' + $scope.fooId + ' but really: ' + id);
    };
});

app.directive('appDropDown', function () {
    return {
        restrict: 'E',
        replace: true,
        scope: {
            model: '=',
            options: '=',
            onChange: '='
        },
        template:
            '<div><select ng-model="model" ng-options="a[optValue] as a[optLabel] for a in options" ng-change="changed()"></select></div>',
        link: function (scope, element, attrs) {
            scope.optValue = attrs.optValue;
            scope.optLabel = attrs.optLabel;

            scope.changed = function () {
                scope.onChange(scope.model);
            };
        }
    };
});

コンソール ログ:

変更: -1 しかし、実際には: 1

変更: 1 しかし実際には: 2

選択を A に変更すると、次に B に変更されます。

更新中ですが、ng-change がトリガーされた後です。

明らかに、ID を渡す (私のように) か、値のコントローラーで $watch を使用することでこれを回避できますが、これは特定のより複雑なシナリオには理想的ではありません。

何か案は?

4

1 に答える 1

1

これは事実の少し後であることは知っていますが、同様の問題があり、周りを検索すると、この質問も見つかりました。本当の答えがないように見えるので、将来誰かを助けるかもしれないので、私がやったことを投稿することを考えました. これは私の場合(そしてあなたのフィドルも)うまくいくようですが、私はAngularJSを使い始めたばかりなので、「ルール」に反して何かをしている可能性があるので、専門家なら誰でも自由に修正してください...

とにかく、ここに私の変更を加えたあなたのフィドルの更新版があります:

http://jsfiddle.net/5vb5oL7e/1/

ディレクティブの実際のコードは次のとおりです。

app.directive('appDropDown', function () {
  return {
    restrict: 'E',
    replace: true,
    scope: {
        model: '=',
        options: '=',
        onChange: '='
    },
    template:
        '<div><select ng-model="model" ng-options="a[optValue] as a[optLabel] for a in options"></select></div>',
    link: function (scope, element, attrs) {
        scope.optValue = attrs.optValue;
        scope.optLabel = attrs.optLabel;
        scope.$watch('model', function(newValue, oldValue)
        {
          // Execute function on change
          if (scope.onChange !== undefined &&
            newValue !== undefined && oldValue !== undefined)
          {
            scope.onChange();
          }
        });
    }
  };
});

基本的には、モデルのリンク機能内にウォッチを追加しました。このウォッチ内で、定義されたときに onChange 関数を起動します。ページの読み込み時に関数が不必要に変更されるのを防ぐために、古い値と新しい値の未定義の追加チェックが追加されました。

これが誰かに役立つことを願っています...

よろしく、ハイノ

于 2014-10-09T12:50:25.990 に答える