【问题标题】:Conditionally setting the class on the option tag with AngularJS使用 AngularJS 有条件地在选项标签上设置类
【发布时间】:2014-06-11 10:03:10
【问题描述】:

这几天我一直在为一个问题苦苦挣扎。我正在尝试根据绑定到的模型中的值将类应用于选项标签。我尝试按照这篇文章 (How to use ng-class in select with ng-options) 的描述使用 ng-Class,但这不起作用。因此,我尝试使用该帖子中的指令,但这也不起作用。我的问题似乎出在表达式中,因为它要么始终为真,要么始终为假,并且从不基于模型中的值。我不确定这是否与 $parse 如何处理表达式有关。这是视图:

<div class="col-md-2">
    <div class="merchant-list">
        <input type="checkbox"
            ng-model="allMerchants"
            ng-change="allMerchants_Changed()">All merchants<br />
        <select size="10"
            ng-model="overviewCtrl.currentMerchant"
            ng-options="item.Id as item.Name for item in allMerchantData"
            ng-disabled="allMerchants"
            ng-change="currentMerchant_Changed()"
            options-class="{ 'merchant-item-waiting':item.status=='w','merchant-item-error':item.status=='e','merchant-item-loaded':item.status=='l'}"
            >
            <option value="">--All Merchants--</option>
        </select>
        <p>Current Merchant: [{{ overviewCtrl.currentMerchant }}]</p>
    </div>
</div>

这是我在返回数据时设置模型状态的方式。

MerchantService.getAllMerchantData().query(function (response) {
        // Add a status flag to the merchant.  waiting, loaded, error
        for (var merchant in response)
        {
            response[merchant].status = 'w';
        }

        $scope.allMerchantData = response;
        SystemMetricService.loadSystemMetrics(response, $scope);
    }, function (error) {
        SharedService.logError("Error getting all merchant data", error);
    });

作为参考,这里是指令,所以你不必去How to use ng-class in select with ng-options

angular.module('app.directives')
.directive('optionsClass', function ($parse) {
    return {
        require: 'select',
        link: function (scope, elem, attrs, ngSelect) {
            // get the source for the items array that populates the select.
            var optionsSourceStr = attrs.ngOptions.split(' ').pop(),
            // use $parse to get a function from the options-class attribute
            // that you can use to evaluate later.
                getOptionsClass = $parse(attrs.optionsClass);

            scope.$watch(optionsSourceStr, function (items) {
                // when the options source changes loop through its items.
                angular.forEach(items, function (item, index) {
                    // evaluate against the item to get a mapping object for
                    // for your classes.
                    var classes = getOptionsClass(item),
                    // also get the option you're going to need. This can be found
                    // by looking for the option with the appropriate index in the
                    // value attribute.
                        option = elem.find('option[value=' + index + ']');

                    // now loop through the key/value pairs in the mapping object
                    // and apply the classes that evaluated to be truthy.
                    angular.forEach(classes, function (add, className) {
                        if (add) {
                            angular.element(option).addClass(className);
                        }
                    });
                });
            });
        }
    };
});

【问题讨论】:

    标签: angularjs angularjs-directive


    【解决方案1】:

    正如您所怀疑的,它与 $parse 有关。

    你写

    options-class="{ 'merchant-item-waiting':item.status=='w','merchant-item-error':item.status=='e','merchant-item-loaded':item.status=='l'
    

    注意您是如何明确引用item.status 的。按照原来的例子,你应该改写status

    现在,这是为什么呢?查看 $parse (https://docs.angularjs.org/api/ng/service/$parse) 的文档,我们看到了这部分:

    Returns function(context, locals) - a function which represents the compiled expression:
    
    context – {object} – an object against which any expressions embedded in the strings are evaluated against (typically a scope object).
    

    在指令中我们有部分:

    var classes = getOptionsClass(item),
    

    这意味着在这种情况下,您可以将 item(选项之一)视为类似于作用域,因为您不会在代码中编写 scope.status,而只需引用 status

    【讨论】:

    • 谢谢 SveinT!就是这样。感谢您找到问题并详细解释。我现在可以感觉到我的头发变得不那么灰了。
    猜你喜欢
    • 1970-01-01
    • 2012-08-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-07-02
    • 2017-11-19
    • 2012-04-27
    • 1970-01-01
    相关资源
    最近更新 更多