如何在AngularJS中进行双向过滤? [英] How to do two-way filtering in AngularJS?

查看:203
本文介绍了如何在AngularJS中进行双向过滤?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

AngularJS可以做的一件有趣的事情是将过滤器应用于特定的数据绑定表达式,这是一种应用的便捷方式,例如,特定于文化的货币或模型属性的日期格式。在范围上计算属性也很好。问题是这些功能都不适用于双向数据绑定方案 - 只是从范围到视图的单向数据绑定。这在一个优秀的图书馆中似乎是一个明显的遗漏 - 或者我错过了什么?

One of the interesting things AngularJS can do is apply a filter to a particular databinding expression, which is a convenient way to apply, for example, culture-specific currency or date formatting of a model's properties. It is also nice to have computed properties on the scope. The problem is that neither of these features work with two-way databinding scenarios - only one-way databinding from the scope to the view. This seems to be a glaring omission in an otherwise excellent library - or am I missing something?

KnockoutJS ,我可以创建一个读/写计算属性,它允许我指定一对函数,一个被调用以获取属性的值,另一个被调用时被调用。财产设置。这允许我实现,例如,文化感知输入 - 让用户键入$ 1.24并将其解析为ViewModel中的浮点数,并在输入中反映ViewModel中的更改。

In KnockoutJS, I could create a read/write computed property, which allowed me to specify a pair of functions, one which is called to get the value of the property, and one which is called when the property is set. This allowed me to implement, for example, culture-aware input - letting the user type "$1.24" and parsing that into a float in the ViewModel, and have changes in the ViewModel reflected in the input.

我能找到的最接近的是使用 $ scope。$ watch(propertyName,functionOrNGExpression); 这允许我在 $ scope 中的属性发生更改时调用函数。但这并不能解决例如文化意识的输入问题。当我尝试在 $ watch 方法中修改 $ watched 属性时,请注意这些问题:

The closest thing I could find similar to this is the use of $scope.$watch(propertyName, functionOrNGExpression); This allows me to have a function invoked when a property in the $scope changes. But this doesn't solve, for example, the culture-aware input problem. Notice the problems when I try to modify the $watched property within the $watch method itself:

$scope.$watch("property", function (newValue, oldValue) {
    $scope.outputMessage = "oldValue: " + oldValue + " newValue: " + newValue;
    $scope.property = Globalize.parseFloat(newValue);
});

http://jsfiddle.net/gyZH8/2/

当用户开始输入时,输入元素会变得非常混乱。我通过将属性拆分为两个属性来改进它,一个用于未解析的值,另一个用于解析的值:

The input element gets very confused when the user starts typing. I improved it by splitting the property into two properties, one for the unparsed value and one for the parsed value:

$scope.visibleProperty= 0.0;
$scope.hiddenProperty = 0.0;
$scope.$watch("visibleProperty", function (newValue, oldValue) {
    $scope.outputMessage = "oldValue: " + oldValue + " newValue: " + newValue;
    $scope.hiddenProperty = Globalize.parseFloat(newValue);
});

http://jsfiddle.net/XkPNv/1/

这是对第一个版本的改进,但是更多一点详细,并注意到范围更改的 parsedValue 属性仍然存在问题(在第二个输入中键入内容,这会更改 parsedValue 直接注意顶部输入没有更新)。这可能发生在控制器操作或从数据服务加载数据。

This was an improvement over the first version, but is a bit more verbose, and notice that there is still an issue of the parsedValue property of the scope changes (type something in the second input, which changes the parsedValue directly. notice the top input does not update). This might happen from a controller action or from loading data from a data service.

是否有一些更简单的方法来使用AngularJS实现此方案?我是否遗漏了文档中的一些功能?

Is there some easier way to implement this scenario using AngularJS? Am I missing some functionality in the documentation?

推荐答案

事实证明,这是一个非常优雅的解决方案,但它不是很好记录。

It turns out that there's a very elegant solution to this, but it's not well documented.

格式化显示的模型值可由 | 运算符和角度格式化。事实证明,ngModel不仅包含格式化程序列表,还包含解析器列表。

Formatting model values for display can be handled by the | operator and an angular formatter. It turns out that the ngModel that has not only a list of formatters but also a list of parsers.

<input type="text" ng-model="foo.bar"></input>



2。在角度模块中创建一个指令,该指令将应用于同一元素,并且取决于 ngModel 控制器



2. Create a directive in your angular module that will be applied to the same element and that depends on the ngModel controller

module.directive('lowercase', function() {
    return {
        restrict: 'A',
        require: 'ngModel',
        link: function(scope, element, attr, ngModel) {
            ...
        }
    };
});



3。在链接方法中,将自定义转换器添加到 ngModel 控制器



3. Within the link method, add your custom converters to the ngModel controller

function fromUser(text) {
    return (text || '').toUpperCase();
}

function toUser(text) {
    return (text || '').toLowerCase();
}
ngModel.$parsers.push(fromUser);
ngModel.$formatters.push(toUser);



4。将新指令添加到已经具有 ngModel



4. Add your new directive to the same element that already has the ngModel

<input type="text" lowercase ng-model="foo.bar"></input>

这是工作示例,在输入中将文本转换为小写,并在模型中返回大写

Here's a working example that transforms text to lowercase in the input and back to uppercase in the model

模型控制器的API文档也有一个简要介绍解释和其他可用方法的概述。

The API Documentation for the Model Controller also has a brief explanation and an overview of the other available methods.

这篇关于如何在AngularJS中进行双向过滤?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆