0

angular の JQM ライブラリを使用して問題が発生しました。特に、jqmFlip ディレクティブを使用してフィルター ボタンを作成しようとしています。

ディレクティブに ng-model 属性を追加すると、DOM でデータ バインディングが正常に機能します。しかし、コントローラーから ng-model の値をログに記録しようとすると、空白の文字列として表示されます (ng-model を次のように定義する必要があるため:

$scope.search = {
 includeTags:"",
 includeKeywords:""
};

そうしないと、変数は未定義になります。

ただし、ログ ステートメントの前に $scope.$apply() を呼び出すことで、正しい値をログに記録できます。

私が理解していることから、これは次のエラーが表示されるため、値を取得するための最良の方法ではありません: $digest already in progress.

なぜこれが起こっているのかについてのアイデアはありますか? 必要に応じて、さらにコードを投稿できます。

更新: ディレクティブ コード

jqmModule.directive('jqmFlip', [function () {
return {
    restrict: 'E',
    transclude: true,
    replace: true,
    templateUrl: 'templates/jqmFlip.html',
    scope: {
        onLabel: '@',
        onValue: '@',
        offLabel: '@',
        offValue: '@',
        mini: '@',
        disabled: '@',
        defaultValue: '@'
    },
    require: ['?ngModel', '^?jqmControlgroup'],
    link: function (scope, element, attr, ctrls) {
        console.log(ctrls);
        var ngModelCtrl = ctrls[0];
        var jqmControlGroupCtrl = ctrls[1];
        var parsedOn;
        var parsedOff;

        scope.theme = scope.$theme || 'c';
        scope.isMini = isMini;
        scope.onValue = angular.isDefined(attr.onValue) ? scope.onValue : true;
        scope.offValue = angular.isDefined(attr.offValue) ? scope.offValue : false;
        scope.defaultValue = attr.defaultValue;


        initToggleState();
        bindClick();

        function initToggleState () {
            ngModelCtrl.$parsers.push(parseBoolean);
            parsedOn = parseBoolean(scope.onValue);
            parsedOff = parseBoolean(scope.offValue);
            ngModelCtrl.$render = updateToggleStyle;
            ngModelCtrl.$viewChangeListeners.push(updateToggleStyle);
        }

        function updateToggleStyle () {
            updateNaNAsOffValue(scope.defaultValue);
            var toggled = isToggled();
            scope.toggleLabel = toggled ? scope.onLabel : scope.offLabel;
            scope.onStyle = toggled ? 100 : 0;
            scope.offStyle = toggled ? 0 : 100;
        }

        // this has to be done in the change listener,
        // otherwise the potential scope value would be overwritten with the off value
        function updateNaNAsOffValue (defaultValue) {
            if (!ngModelCtrl.$viewValue) {
                ngModelCtrl.$setViewValue(defaultValue);
            }
        }

        function bindClick () {
            scope.toggle = function () {
                ngModelCtrl.$setViewValue(isToggled() ? parsedOff : parsedOn);
            };
        }

        function isToggled () {
            return ngModelCtrl.$viewValue === parsedOn;
        }

        function isMini() {
            return scope.mini || (jqmControlGroupCtrl && jqmControlGroupCtrl.$scope.mini);
        }

        function parseBoolean(value) {
            if (value === 'true') {
                return true;
            } else if (value === 'false') {
                return false;
            }
            return value;
        }
    }
};
}]);

jqmFlip ディレクティブに必要な JQMcontrolGroup ディレクティブ:

jqmModule.directive('jqmControlgroup', function() {
return {
    restrict: 'A',
    replace: true,
    transclude: true,
    templateUrl: 'templates/jqmControlgroup.html',
    scope: {
        mini: '@',
        iconpos: '@',
        type: '@',
        shadow: '@',
        corners: '@',
        legend: '@'
    },
    controller: ['$scope', JqmControlGroupCtrl]
};

function JqmControlGroupCtrl($scope) {
    this.$scope = $scope;
}
});

jqmFlip テンプレートの URL:

angular.module("templates/jqmFlip.html", []).run(["$templateCache", function($templateCache) {
$templateCache.put("templates/jqmFlip.html",
"<div jqm-scope-as=\"jqmFlip\">\n" +
"        <label class=\"ui-slider\" ng-transclude></label>\n" +
"        <div class=\"ui-slider ui-slider-switch ui-btn-down-{{$scopeAs.jqmFlip.theme}} ui-btn-corner-all\"\n" +
"             jqm-class=\"{'ui-disabled': $scopeAs.jqmFlip.disabled,\n" +
"                        'ui-mini': $scopeAs.jqmFlip.isMini()}\"\n" +
"             ng-click=\"$scopeAs.jqmFlip.toggle()\">\n" +
"             <span class=\"ui-slider-label ui-slider-label-a ui-btn-active ui-btn-corner-all\" ng-style=\"{width: $scopeAs.jqmFlip.onStyle + '%'}\">{{$scopeAs.jqmFlip.onLabel}}</span>\n" +
"             <span class=\"ui-slider-label ui-slider-label-b ui-btn-down-{{$scopeAs.jqmFlip.theme}} ui-btn-corner-all\" ng-style=\"{width: $scopeAs.jqmFlip.offStyle + '%'}\">{{$scopeAs.jqmFlip.offLabel}}</span>\n" +
"                <div class=\"ui-slider-inneroffset\">\n" +
"                  <a class=\"ui-slider-handle ui-slider-handle-snapping ui-btn ui-btn-corner-all ui-btn-up-{{$scopeAs.jqmFlip.theme}} ui-shadow\"\n" +
"                     title=\"{{$scopeAs.jqmFlip.toggleLabel}}\"\n" +
"                     ng-style=\"{left: $scopeAs.jqmFlip.onStyle + '%'}\">\n" +
"                    <span class=\"ui-btn-inner\"><span class=\"ui-btn-text\"></span></span>\n" +
"                  </a>\n" +
"                </div>\n" +
"        </div>\n" +
"</div>\n" +
"");
}]);

jqmControlGroup テンプレートの URL:

angular.module("templates/jqmControlgroup.html", []).run(["$templateCache", function($templateCache) {
$templateCache.put("templates/jqmControlgroup.html",
"<fieldset class=\"ui-controlgroup\"\n" +
"     jqm-class=\"{'ui-mini': mini, 'ui-shadow': shadow, 'ui-corner-all': corners!='false',\n" +
"     'ui-controlgroup-vertical': type!='horizontal', 'ui-controlgroup-horizontal': type=='horizontal'}\">\n" +
"    <div ng-if=\"legend\" class=\"ui-controlgroup-label\">\n" +
"        <legend>{{legend}}</legend>\n" +
"    </div>\n" +
"    <div class=\"ui-controlgroup-controls\" ng-transclude jqm-position-anchor></div>\n" +
"</fieldset>\n" +
"");
}]);

HTML での参照:

<jqm-flip mini="true" jqm-theme="d" ng-model="search.includeTags" on-label="On" on-value="1" off-label="Off" 
         off-value="0" default-value="1"></jqm-flip>
          {{search.includeTags}}
4

0 に答える 0