在级联下拉菜单中使用敲除和微风 [英] Using Knockout and Breeze with Cascading Dropdowns

查看:72
本文介绍了在级联下拉菜单中使用敲除和微风的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

所以我现在已经来回很长时间了,所以我要讲到重点.

So I've been at this back and forth for quite a long time now, so I'll just get to the point.

我正在基于HotTowel模板创建一个应用程序,因此我使用了敲除,微风,Q等.我正在使用微风查询从服务器中获取一些数据,然后将这些数据加载到第一个中.选择(作为选项).这将更改selectedModel可观察和订阅触发器(订阅是当前的解决方案",我使用了具有相同结果的数据绑定等).然后,订阅将使用新的selectedModel值,并使用它来获取第二个可观察值的数据.该查询也会通过,并且结果存储在modelProperties可观察数组中,但是UI不会更新第二个选择(它为空).奇怪的是,按ctrl + F5(我连续尝试了50次)总是可以正确填充它,但是从不加载第一次加载.

I am creating an application based on the HotTowel template, so I'm using knockout, breeze, Q etc. I'm using a breeze query to get some data from the server, and then I load that data into the first select (as options). This changes the selectedModel observable and the subscription triggers ( the subscription is the current "solution", I have used data-bind etc with the same results). The subscription then takes the new selectedModel value and uses it to get data for the second observable. This query also passes and the results are stored in the modelProperties observable array, yet the UI does NOT update the second select (it's empty). The strange thing is, pressing ctrl + F5 (i tried about 50 times in a row) always populates it correctly, but NEVER on the first load.

TLDR; 2选择,第一个选项的选定选项定义对第二个选项的查询.查询工作,可观察变量得到填充,始终始终填充第一选择,其次从不在第一次启动时启动,而是始终在以下ctrl + F5上启动.

TLDR; 2 selects, selected option of the first one defines the query for the options of the second one. Queries work, observables get populated, first select is always populated, second never on first boot but always on the following ctrl+F5.

以下是有关此应用程序的一些摘录: 视图模型:

Here are some snippets regarding this piece of the application: The viewmodel:

define(['services/logger', 'services/datacontext'], function (logger, datacontext) {
    var models = ko.observableArray();
    var modelProperties = ko.observableArray();
    var selectedModel = ko.observable();
    var init = true;

    function activate() {
        logger.log('Search View Activated', null, 'search', true);
        return datacontext.getModels(models);
    }

    var sub = selectedModel.subscribe(function (newValue) {
        return datacontext.getModelProperties(modelProperties, newValue);
    });

    var vm = {
        activate: activate,
        models: models,
        selectedModel: selectedModel,
        modelProperties: modelProperties,
        title: 'Search View'
    };

    return vm;

视图的代码:

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <title></title>
</head>
<body id="one">
    <select id="entitySelect" class ="entitySelect" name="first"
        data-bind="options: models, value: selectedModel">
    </select>
    <select id="propertySelect" class ="propertySelect" data-bind=
    'options:modelProperties'></select>
</body>
</html>

以及数据上下文中的方法:

And the methods in the datacontext:

        var getModels = function (modelsObservable) {
        var query = EntityQuery.from('Models');
        return manager.executeQuery(query)
            .then(querySucceeded)
            .fail(queryFailed);

        function querySucceeded(data) {
            logger.log("Query succeeded", true);
            logger.log(data);
            if (modelsObservable) {
                modelsObservable(data.results);
            }
            logger.log('Retrieved [Models] from remote data source',
                data, true);
        }
        function queryFailed(data) {
            logger.log(data.toString(), data, true);
        }
    };

    var getModelProperties = function (propertiesObservable,modelName) {
        var query = EntityQuery.from('ModelProperties').withParameters({ name: modelName });
        return manager.executeQuery(query)
            .then(querySucceeded)
            .fail(queryFailed);

        function querySucceeded(data) {
            logger.log("Query succeeded", null, true);
            logger.log(data);
            if (propertiesObservable) {
                propertiesObservable(data.results);
            }
            logger.log('Retrieved [Properties] from remote data source',
                data, true);
        }
        function queryFailed(data) {
            logger.log(data.toString(), data, true);
        }
    };

我想再次指出,所有查询都通过了,并且observableArrays确实填充了结果(已通过.peek()检查).

Once again I'd like to point out that all the queries do pass, and the observableArrays do get populated with the results (checked with .peek() ).

以下是一些屏幕快照,用于阐明问题: 从VS首次启动时: http://i.imgur.com/8Gd53Yh.png

Here are some screenshots to clarify the problem: On first boot from VS : http://i.imgur.com/8Gd53Yh.png

然后按Ctrl + F5 http://i.imgur.com/vzO8d70.png

Then, ctrl+F5 http://i.imgur.com/vzO8d70.png

我已经尝试了几乎所有我能想到的东西,并且用谷歌搜索了所有想到的东西,但是都无济于事.任何帮助将不胜感激!另外,这是我在这里的第一篇文章,对于任何错误,我深表歉意!

I have tried pretty much everything I can think of, and googled everything that came to mind, but to no avail. Any help would be greatly appreciated! Also, this is my first post here so I apologize for any mistakes!

推荐答案

以下是一些评论-

您的观点毫无意义.如果您使用的是类似HotTowel模板的模板,那么那里就不需要很多额外的标记,因为您很可能使用Durandal.js进行合成,而额外的标记可能会伤害您.

Your view makes no sense. If you are using something like the HotTowel template then there is a lot of extra mark-up that is not needed there, considering you are most likely using Durandal.js for composition and the additional mark-up could be hurting you.

如果您确实确实在或多或少地加载子视图",那么它应该是这样-

If you are indeed loading a 'subview' more or less then this is what it should look like -

<select id="entitySelect" class ="entitySelect" name="first" data-bind="options: models, value: selectedModel"></select>
<select id="propertySelect" class ="propertySelect" data-bind='options:modelProperties'></select>

接下来,如果您使用级联下拉菜单,我之前已经提到了此方法,因此我强烈建议所有人使用.通过ko.computed使您的第二个依赖于您的第一个.

Next, if you are using cascading dropdowns I have mentioned this method before and I strongly suggest it for everyone. Make your second dependent on your first with a ko.computed.

var models = ko.observableArray();
var modelProperties = ko.computed(function () {
    var modelArr = ko.observableArray();
    if (!selectedModel()) { return modelArr; }
    datacontext.getModelProperties(modelArr, selectedModel().then(function() { return modelArr(); });
});

现在,在选择模型之前,modelProperties将为空,然后它将消失并获取该模型的属性.

Now modelProperties will be null until you select a model, then it will go out and get the properties of that model.

理解正在使用的函数声明之间的区别也很重要. var myFunc = function(){};是构造函数,将在视图模型实例化时立即求值.函数myFunc(){}是标准函数,将等到被调用后再求值.

It's also important to understand the difference between the function declarations you are using. var myFunc = function () {}; is a constructor function and will evaluate immediately on view model instantiation. function myFunc () {} is a standard function and will wait until called before evaluating.

这篇关于在级联下拉菜单中使用敲除和微风的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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