Javascript 主干.Wreqr请求响应处理程序的回调响应/状态(完成时)

Javascript 主干.Wreqr请求响应处理程序的回调响应/状态(完成时),javascript,marionette,jquery-deferred,backbone-events,Javascript,Marionette,Jquery Deferred,Backbone Events,使用jquery deferred.resolve方法的通常方法是,当您有一个回调函数时调用该方法,该函数会向您提供一个已完全加载的响应,在本例中,xhr会在加载事件侦听器时添加一个事件侦听器,并向deferred.resolve提供xhr响应 下面的代码是从一个示例中复制的。 我的当前代码使用木偶请求-响应处理程序检索数据。我是否可以从以下请求获得回调响应 function getData(activityID) { var defer = $.Deferred(); require

使用jquery deferred.resolve方法的通常方法是,当您有一个回调函数时调用该方法,该函数会向您提供一个已完全加载的响应,在本例中,xhr会在加载事件侦听器时添加一个事件侦听器,并向deferred.resolve提供xhr响应

下面的代码是从一个示例中复制的。

我的当前代码使用木偶请求-响应处理程序检索数据。我是否可以从以下请求获得回调响应

function getData(activityID) {
  var defer = $.Deferred();
  require(["entities/element/element_collection"], function() {
    var fetchData = App.request("element:entities:initialize", activityID);
    //Example code scenario
    // How do i know my request is being fulfilled? and used Deferred.resolve accordingly.
    //maybe something as follows?
     fetchData.success(function(response){
        defer.resolve(response);
     }); 
     //Example code scenario 

  });

  return defer.promise();
};
请求处理程序基本上将返回一个主干集合,该集合将通过将对象集合传递到新的主干集合中来生成。

如果(看起来)
require()
是异步的,并且
App.request()
是同步的,那么您可以按如下方式编写代码:

function getData(activityID) {
  var defer = $.Deferred();
  require(["entities/element/element_collection"], function() {
    var fetchData = App.request("element:entities:initialize", activityID);
    defer.resolve(fetchData);
  });
  return defer.promise();
};

getData(activityID).done(function(fetchData) {
    //do awesome stuff with fetchData here
});
function getData() {
  var defer = $.Deferred();
  require(["entities/element/element_collection"], defer.resolve);
  return defer.promise();
};

getData().done(function() {
    var fetchData = App.request("element:entities:initialize", activityID);
    //do awesome stuff with fetchData here
});
或者,根据您想在
getData()
中执行多少操作,如下所示:

function getData(activityID) {
  var defer = $.Deferred();
  require(["entities/element/element_collection"], function() {
    var fetchData = App.request("element:entities:initialize", activityID);
    defer.resolve(fetchData);
  });
  return defer.promise();
};

getData(activityID).done(function(fetchData) {
    //do awesome stuff with fetchData here
});
function getData() {
  var defer = $.Deferred();
  require(["entities/element/element_collection"], defer.resolve);
  return defer.promise();
};

getData().done(function() {
    var fetchData = App.request("element:entities:initialize", activityID);
    //do awesome stuff with fetchData here
});
但是,如果
App.request()
也是异步的,那么它就不能返回数据-它必须返回数据承诺,代码如下:

function getData(activityID) {
  var defer = $.Deferred();
  require(["entities/element/element_collection"], function() {
    App.request("element:entities:initialize", activityID).done(defer.resolve);
  });
  return defer.promise();
};

getData(activityID).done(function(fetchData) {
    //do awesome stuff with fetchData here
});
或:


如果
App.request()
是异步的,既不返回承诺也不接受回调,那么需要与编写它的人联系
App.request()
需要重写,或者您需要找到另一个实用程序来执行此任务。

从服务器获取数据默认为异步调用,那么您为什么不使用命令而不是请求/响应并侦听模型事件呢?我想这会容易些。 在这个话题上,我会创建一个频道

  • 获取数据的命令
  • 通道应用于的模型或集合实例
  • 然后,控制器只需订阅通道即可获取数据,并将侦听集合实例事件(同步错误更改,您想要的模型/集合上的任何基本主干事件)

    /*常量:模拟API数据*/
    常数={};
    Constants.jsonLanguages=[
    {名称:“英语”,代码:“en”,可编辑:true},
    {名称:“法语”,代码:“fr”,isEditable:false},
    {名称:“德语”,代码:“de”,可编辑:true},
    {名称:“西班牙语”,代码:“es”,isEditable:false}
    ];
    Constants.jsonBook={
    标题:“沙丘”,
    作者姓名:“弗兰克·赫伯特”,
    语言代码:“en”,
    ISBN:“978-1-4493-9268-0”
    };
    /* ----------------------------------------------------------------------------- */
    /*模型*/
    //语言/模型.js
    var模型={};
    models.Language=Backbone.Model.extend({
    默认值:{
    名称:“英语”,
    代码:“en”
    },
    idAttribute:“代码”,
    url:“/echo/json/”
    });
    models.LanguageCollection=Backbone.Collection.extend({
    模型:模型,语言,
    url:“/echo/json/”
    });
    //Book/Models.js
    models.Book=Backbone.Model.extend({
    默认值:{
    标题:“,
    作者姓名:“,
    语言:空
    },
    url:“/echo/json/”,
    idAttribute:“ISBN”
    });
    /* ----------------------------------------------------------------------------- */
    /*通道:管理服务器和客户端之间的数据。
    -依赖项:wreqr、相关模型、相关路由*/
    //语言/Channel.js
    var LanguageChannel={};
    LanguageChannel.data={};
    LanguageChannel.data.workingLanguage=新模型。语言();
    LanguageChannel.data.languages=新模型。LanguageCollection();
    LanguageChannel.channel=Backbone.Wreqr.radio.channel(“语言”);
    LanguageChannel.channel.commands.setHandler(“getLanguages”,function()){
    //在这里,您通常使用主干收集和主干路由器获取数据
    window.console&&console.log(“LanguageChannel.channel.command.getLanguages()”;
    LanguageChannel.data.languages.reset(Constants.jsonLanguages);
    LanguageChannel.data.languages.trigger(“同步”);
    });
    //Books/Channel.js
    var BookChannel={};
    BookChannel.data={};
    BookChannel.data.book=新模型.book();
    BookChannel.channel=Backbone.Wreqr.radio.channel(“Books”);
    BookChannel.channel.commands.setHandler(“getBook”,函数(id){
    //在这里,您通常使用主干模型和主干路由器获取数据
    window.console&&console.log(“bookschannel.channel.commands.getBook”(+id+));
    bookschannel.data.book.set(Constants.jsonBook,{reset:true});
    BookChannel.data.book.trigger(“同步”);
    });
    /* ----------------------------------------------------------------------------- */
    /*视图:管理模板和查看事件*/
    //Book/Views.js
    BookAttributesView=Marionette.ItemView.extend({
    el:#BookAttributesBox“,
    模板:“#BookAttributesTemplate”,
    绑定:
    {
    “#头衔”:“头衔”,
    “#AuthorName”:“AuthorName”,
    “#语言代码”:{
    注意:“语言代码”,
    选择选项:{
    集合:LanguageChannel.data.languages,
    标签路径:“名称”,
    valuePath:“代码”
    },
    更新:功能($el、val、型号、选项){
    window.console&&console.log(“View.bindings.#LanguagageCode:update”);
    LanguageChannel.data.languages.each(函数(语言){
    //找到父母。
    var parent=$el.find(“#LanguageReadable”);
    if(language.get(“isEditable”)){
    父项=$el.find(“#语言可编辑”);
    }
    //选择正确的值。
    var selected=“”;
    if(language.get(“Code”)==val){
    选定='selected=“selected”';
    }
    //将选项添加到optgroup。
    parent.append(“+language.get(“Name”)+”);
    });
    }
    }
    },
    onRender:function(){
    window.console&&console.log(“View.onRender”);
    这个.stickit();
    }
    });
    /* ----------------------
    
    /* Constants: Simulation of API data. */
    Constants = {};
    
    Constants.jsonLanguages = [
        {Name: "English", Code: "en", isEditable:true},
        {Name: "French", Code: "fr", isEditable:false},
        {Name: "German", Code: "de", isEditable:true},
        {Name: "Spanish", Code: "es", isEditable:false}
    ];
    
    Constants.jsonBook = {
        Title: "Dune",
        AuthorName: "Frank Herbert",
        LanguageCode: "en",
        ISBN: "978-1-4493-9268-0"
    };
    
    
    
    /* ----------------------------------------------------------------------------- */
    /* Models */
    
    // Language/Models.js
    var models = {};
    models.Language = Backbone.Model.extend({
        defaults: {
            Name: "English",
            Code: "en"
        },
        idAttribute:"Code",
        url: "/echo/json/"
    });
    
    models.LanguageCollection = Backbone.Collection.extend({
        model: models.Language,
        url: "/echo/json/"
    });
    
    // Book/Models.js
    models.Book = Backbone.Model.extend({
        defaults: {
            Title: "",
            AuthorName: "",
            Language: null
        },
        url: "/echo/json/",
        idAttribute: "ISBN"
    });
    
    
    
    /* ----------------------------------------------------------------------------- */
    /* Channels: Manage data between server and client. 
        - dependencies : wreqr, related models, related routes */
    // Languages/Channel.js
    var LanguageChannel = {};
    LanguageChannel.data = {};
    LanguageChannel.data.workingLanguage = new models.Language();
    LanguageChannel.data.languages = new models.LanguageCollection();
    LanguageChannel.channel = Backbone.Wreqr.radio.channel("Languages");
    LanguageChannel.channel.commands.setHandler("getLanguages", function() {
        // here you typically fetch the data using backbone collection and backbone router
        window.console && console.log("LanguageChannel.channel.command.getLanguages()");
        LanguageChannel.data.languages.reset(Constants.jsonLanguages);
        LanguageChannel.data.languages.trigger("sync");
    });
    
    // Books/Channel.js
    var BookChannel = {};
    BookChannel.data = {};
    BookChannel.data.book = new models.Book();
    BookChannel.channel = Backbone.Wreqr.radio.channel("Books");
    BookChannel.channel.commands.setHandler("getBook", function(id){
        // here you typically fetch the data using backbone model & backbone router
        window.console && console.log("BookChannel.channel.commands.getBook(" + id +")");
        BookChannel.data.book.set(Constants.jsonBook, {reset:true});
        BookChannel.data.book.trigger("sync");
    });
    
    /* ----------------------------------------------------------------------------- */
    /* Views: Manage template and view events. */
    
    // Book/Views.js
    BookAttributesView = Marionette.ItemView.extend({
        el: "#BookAttributesBox",
        template: "#BookAttributesTemplate",
        bindings:
        {
            "#Title": "Title",
            "#AuthorName": "AuthorName",
            "#LanguageCode": {
                observe: "LanguageCode",
                selectOptions: {
                    collection: LanguageChannel.data.languages,
                    labelPath: "Name",
                    valuePath: "Code"
                },
                update: function($el, val, model, options) {
                    window.console && console.log("View.bindings.#LanguagageCode:update");
                    LanguageChannel.data.languages.each(function(language){
                        // Find parent.
                        var parent = $el.find("#LanguageReadable");
                        if (language.get("isEditable")){
                            parent = $el.find("#LanguageEditable");
                        }
    
                        // Select correct value.
                        var selected = "";
                        if (language.get("Code") == val){
                            selected = ' selected="selected"';
                        }
    
                        // Add option to optgroup.
                        parent.append("<option" + selected + ">" + language.get("Name") + "</option>");
                    });
                }
            }
        },
        onRender: function () {
            window.console && console.log("View.onRender");
            this.stickit();
        }
    });
    
    
    
    /* ----------------------------------------------------------------------------- */
    /* Controllers: Manage page behaviour. */
    
    // Books/Controller.js: 
    BookController = Marionette.Controller.extend({
        initialize: function(){
            window.console && console.log("Controller.ctor");
            var self = this;
            self.bookId = "978-1-4493-9268-0" 
            // Callbacks from data channels.
            self.listenTo(LanguageChannel.data.languages, "sync", self.onSyncLanguages);                           
            self.listenTo(BookChannel.data.book, "sync", self.onSyncBook);
    
            // Retrieve data.
            LanguageChannel.channel.commands.execute("getLanguages");
            BookChannel.channel.commands.execute("getBook", self.bookId);
        },
        /* Book functions */
        onSyncBook: function(){
            window.console && console.log("Controller.onSyncBook");
            this.showBookAttributes(); // TODO, use : LanguageChannel.data.languages.fetch();
        },
        showBookAttributes: function(){
            window.console && console.log("Controller.showBookAttributes");
            new BookAttributesView({ model: BookChannel.data.book }).render();
        },
        /* Language functions */
        onSyncLanguages: function(){
            window.console && console.log("Controller.onSyncLanguages")
            this.showBookAttributes();
        }
    });
    
    
    
    /* ----------------------------------------------------------------------------- */
    /* Aplication.js: Starts the backbone application (main entry point). */
    
    // Book/Application.js
    Application = Marionette.Application.extend({
        onStart: function(){
            window.console && console.log("Application.start()");
            new BookController();
        }    
    });