1

次のディレクティブがあります。

app.directive('scMultiselect', [function() {
    return {
        link: function(scope, element, attrs) {
            element = $(element[0]);

            element.multiselect({
                enableFiltering: true,

                // Replicate the native functionality on the elements so
                // that Angular can handle the changes for us
                onChange: function(optionElement, checked) {
                    optionElement.prop('selected', false);

                    if (checked)
                        optionElement.prop('selected', true);

                    element.change();
                }
            });

            scope.$watch(function () {
                return element[0].length;
            }, function () {
                element.multiselect('rebuild');
            });

            scope.$watch(attrs.ngModel, function() {
                element.multiselect('refresh');
            });
        }
    };
}]);

そして、私のパーシャルの次の要素:

<select
    id="level_teachers"
    class="multiselect col-sm-10"
    multiple="multiple"
    ng-model="level.teachers"
    ng-options="teacher.id as teacher.name for teacher in teachers"
    sc-multiselect>
</select>

bootstrap-multiselect コントロールは初期化され、正しく表示されますが、その中のエントリを選択すると、モデル ( level.teachers) が空のままになります。

4

2 に答える 2

3

同じ問題があり、これは私にとってはうまくいきました:

まず、リンク関数の 4 番目のパラメーターとして ngModel を追加します。非常に便利です - 詳細はこちら: https://docs.angularjs.org/api/ng/type/ngModel.NgModelController

次に、基本的に onChange メソッドのオプションを ngModel との間で「手動で」追加/削除する必要があります。

ngModel.$setViewValue() は値を更新し、ngModel.$render と scope.$apply() はそれを可視化し、新しいモデルをさらに広げます:)

単一の選択しかない場合は、はるかに簡単です-配列制御がないためコードが少なくなります-$setViewValue()、$render()、および$apply()を使用するだけです。

app.directive('scMultiselect', function() {
    return {
        require: 'ngModel',
        link: function(scope, element, attrs, ngModel) {
            element = $(element[0]);

            element.multiselect({
                enableFiltering: true,
                onChange: function(optionElement, checked) {
                    optionElement.prop('selected', false);

                    var modelValue = ngModel.$modelValue; // current model value - array of selected items
                    var optionText = optionElement[0].text; // text of current option
                    var optionIndex = modelValue.indexOf(optionText); 
                    if (checked) {
                        if ( optionIndex == -1) { // current option value is not in model - add it
                            modelValue.push(optionText)
                        }
                        optionElement.prop('selected', true);
                    } else if ( optionIndex > -1 ) { // if it is - delete it
                        modelValue.splice(optionIndex,1);
                    }

                    ngModel.$setViewValue(modelValue);
                    ngModel.$render();
                    scope.$apply();
                }
            });

            scope.$watch(element[0].length, function () {
                element.multiselect('rebuild');
            });
        }
    };
});

それがあなたにとってもうまくいくことを願っています:)

于 2014-04-20T13:53:08.030 に答える
0

IT はおそらく、Bootstrap コンポーネントが Angularjs で使用できるように構築されていないためです。インスタンス化した後に自分自身を更新する方法がありません。さらに重要なことに、Angularjs の更新プロセスに参加しません。とにかく良いニュースは、誰かが率先して Angularjs でこれらのブートストラップ コンポーネントを書き直して、それらを使用できるようにしたことです。

http://angular-ui.github.io/bootstrap/

Bootstrap 3.x を使用している場合は、最新のものを入手してください。2.3.x に行き詰まっている場合 v0.8 は 2.3.x をサポートする最後のバージョンです

于 2014-04-13T19:45:32.740 に答える