流星中的循环反应模式

时间:2016-04-24 17:47:41

标签: javascript url meteor reactive-programming meteor-blaze

用例(tl; dr):

在搜索页面上,用户选择0个或更多个市场'从下拉列表。然后,搜索结果将过滤为仅显示至少包含其中一个“市场”的结果。或者,用户可以访问带有'市场= A,B,C'查询参数设置,以查看过滤到这些市场的结果。当然,当用户从下拉列表中选择选项时,必须相应地更改URL,以便他们可以书签/共享该URL以与某人共享该视图。这就是问题所在 - 我们希望在下拉列表时更新URL,并在URL执行时更新下拉列表,从而创建循环依赖项。我们如何实现这一点,以便在我改变时不会出现无限循环,正如我目前所经历的那样?

技术实施:

有两个模板:search_pagesearch_filters。后者是前者中包含的组成部分。

search_page中,有一个助手searchFilterArgs(),可以反应性地获得“市场”的价值。来自查询参数(使用universe:reactive-queries),并相应地设置search_filters的数据上下文。它还将setFilters回调传递给组件。当组件调用回调时,search_page将URL中的工作流参数设置为传递的值。

Template.search_page.helpers({
    searchFilterArgs(){
        const instance = Template.instance();

        const splitOrEmptyArray = function(filter_key) {
            if (UniUtils.url.getQuery(filter_key)){
                return UniUtils.url.getQuery(filter_key, false).split(',');
            } else {
                return [];
            }
        };

        return {
            setFilters: instance.setFilters,
            //get each query parameter as a non-reactive source, '' if not set, then convert to array
            selectedMarkets: splitOrEmptyArray('markets'),
        }
    },

...
});

Template.search_page.onCreated(function() {
    this.setFilters = (key, value) => {
        if (UniUtils.url.getQuery(key, true) !== value){
            UniUtils.url.setQuery(key, value);
        }
    };
});

search_filters组件中,Template.currentData()上有一个自动运行,用于设置“市场”的下拉菜单。数据上下文中的值。还有一个' onChange'调用' setFilter'的下拉列表的处理程序下拉列表更改时回调值。

观察到的行为:

加载页面时,工作流程初始化为空。然后,我从下拉列表中选择一个市场(" Sales")。然后页面进入无限循环,更改URL并更改下拉列表。在设置断点时,发现在我更改了下拉值后,使用正确的值触发了回调,并且正确设置了URL查询参数。然后改变组件的数据上下文,这会以某种方式导致下载onChange处理程序触发,但是使用值""而不是" Sales"。

解决方法:

目前,我已更改了searchFilterArgs帮助程序,以非反应方式检索URL查询参数。因此,当首次使用特定URL访问页面时,市场参数将传递到search_filters组件。在此之后,每次更改组件中的下拉列表时,都会触发回调,并更改URL。由于URL是非反应性检索的,因此不会触发下拉列表中的后续更改。它适用于我们之前的用例,其中URL仅在打开页面时设置,之后不会被用户更改。但是,我们现在拥有代表用户更改URL参数的代码,过滤器应相应更新。

你对Meteor中的循环依赖有经验吗?有解决这个问题的模式吗?

(我使用Meteor 1.3.2和Semantic-UI作为下拉列表)。

0 个答案:

没有答案