【问题标题】:knockout subscribe doesn't work when using knockout.validation and knockout.mapping with require.js将 knockout.validation 和 knockout.mapping 与 require.js 一起使用时,knockout subscribe 不起作用
【发布时间】:2014-01-25 13:07:33
【问题描述】:

所以我对此进行了测试,发现当我以这种方式设置代码时,订阅函数永远不会被调用:

app.index.js

requirejs.config({
    "baseUrl": "/Scripts/app/item/",
    "paths": {
        "jquery": "//code.jquery.com/jquery-2.0.3.min",
        "toastr": "/Scripts/lib/toastr",
        "moment": "/Scripts/lib/moment",
        "fu": "/Scripts/lib/jquery.fineuploader-3.8.0",
        "ko": "//cdnjs.cloudflare.com/ajax/libs/knockout/3.0.0/knockout-min",
        "knockout.validation": "/Scripts/lib/knockout.validation",
        "mapping": "/Scripts/lib/knockout.mapping-latest.debug",
        "timeentry": "/Scripts/lib/jquery.timeentry.min",
        "model.obj": "../models/model.obj",
        "timecollection.kobindings":"/Scripts/lib/koBindings/timecollection.kobindings"
    },
    shim: {
        "knockout.validation": ["ko"],
        "mapping": ["ko"]
    }
});


require(["ko"], function (ko) {
    //manually set the global ko property
    window.ko = ko;

    //then bring in knockout validation
    require(["knockout.validation"], function () {
        ko.validation.configure({
            insertMessages: false,
            decorateElement: true,
            errorElementClass: 'error'
        });
        require(["main.index"], function (bs) {
            bs.run();
        });
    });
});

main.index.js

define(['jquery',
        'ko',
        'mapping',
        'indexViewModel',
        'model.obj'],
   function ($, ko, mapping, indexViewModel, obj) {
       var
           run = function () {
               var vm = new indexViewModel();
               var array = [];
               $.getJSON("/api/GetData/", function (data) {
                        mapping.fromJS(val.ObjCollection, {
                               create: function (options) {
                                   return new Obj(options.data);
                               }
                           }, vm.ObjCollection);

               }).done(function(){
                   ko.applyBindings(vm, document.getElementById('#view'));
               });
           };
       return {
           run: run
       };
   });

模型.js

define('model.obj', ['ko', 'moment'], function (ko, moment) {
    var Obj= function (data) {
        var self = this;
        self.Id = data.Id;
        self.Property = ko.observable(data.Property);

        self.Property .subscribe(function () {
            console.log('in here');
        }, self);    
};
    return Obj;
});

如果我删除此代码:

require(["ko"], function (ko) {
        //manually set the global ko property
        window.ko = ko;

        //then bring in knockout validation
        require(["knockout.validation"], function () {
            ko.validation.configure({
                insertMessages: false,
                decorateElement: true,
                errorElementClass: 'error'
            });
            require(["main.index"], function (bs) {
                bs.run();
            });
        });
    });

然后就这样吧:

require(["main.index"], function (bs) {
                    bs.run();
                });

订阅函数会显示console.log,但使用代码,订阅永远不会被调用。

【问题讨论】:

    标签: knockout.js requirejs knockout-mapping-plugin knockout-validation


    【解决方案1】:

    您的代码中有语法错误:

    function ($, ko, mapping, indexViewModel, obj) {
       var
           run = function () {
               var vm = new indexViewModel();
               var array = [];
               $.getJSON("/api/GetData/", function (data) {
                        mapping.fromJS(val.ObjCollection, {
                               create: function (options) {
                                   return new Obj(options.data);
                               }
                           }, vm.ObjCollection);
    

    注意到你确实'return new Obj'(大写),但是模块被注入到函数中作为'obj'(没有大写)。这可以解释为什么你永远不会到达那里(尽管它不能解释为什么淘汰赛验证与它有任何关系)。

    如果这对您没有帮助,请在代码的各个部分设置一些断点,然后单步执行。查看问题出现在哪里。整个部分永远不会被触发,还是只是订阅没有被触发?为什么您希望订阅回调首先触发?您先设置值,然后订阅,但如果您不再更新值,则回调永远不会触发是有意义的。

    【讨论】:

    • 对不起,我用虚拟名称替换了一些对象名称以显示示例。但是你是对的,淘汰验证与你看到的这个特定错误没有任何关系。订阅的原因是我想在此“属性”更新时计算另一个值。
    • 好的,但是您发布的代码中没有任何内容触发订阅回调,所以我想知道是什么触发了它。您应该真正单步执行代码,看看它在哪里停止工作。这两段代码似乎完全不相关,因此现在存在巨大的空白,读者无法填写。
    • 从客户端更新属性时应该触发。即
    • 所以我猜页面仍然可以正常加载?只是订阅不起作用?在这种情况下,在 Obj 构造函数中放置一个断点,看看它是否被命中。如果没有,在 getJSON 回调中放置一个断点,看看它是否被命中。如果没有,请在调用 getJSON 之前放置一个断点并查看它是否命中。等等。成功命中的最后一点将在有问题的代码之前。
    猜你喜欢
    • 2012-09-13
    • 2012-05-31
    • 2013-07-13
    • 1970-01-01
    • 1970-01-01
    • 2013-07-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多