如何从单独文件中的另一个视图调用主干视图函数

Posted

技术标签:

【中文标题】如何从单独文件中的另一个视图调用主干视图函数【英文标题】:How to call a backbone view function from another view in separate files 【发布时间】:2014-11-11 08:59:01 【问题描述】:

我在两个单独的文件中定义了两个主干视图,即: LandingView.js

define([
    'jquery',
    'underscore',
    'backbone',
    'marionette',
    'text!templates/landing/landingTemplate.html',
    'text!templates/invitations/invitationsTemplate.html',
    'views/invitations/InvitationsView',
], function ($, _, Backbone, Marionette, landingTemplate, invitationsTemplate, InvitationsView) 
var LandingView = Backbone.View.extend(
        el : $("#landing"),
        id : 'landing',
        transition : 'slide',

        initialize : function ()               
            this.GetNotificationsCounts();
        ,
        events : 
            'click #invitations' : 'onInvitations',

        ,
        render : function ()  
            var that = this;
            $('.menu li').removeClass('active');
            $('.menu li a[href="#"]').parent().addClass('active');

            this.$el.html(landingTemplate);

        ,
        cleanup: function()  
            this.undelegateEvents();
            $(this.el).empty();
        ,
        onInvitations : function ()  

            //do something
        ,

        GetProfile: function (userLogin) 
               // do something
        ,


        GetNotificationsCounts: function () 
               // do something

        ,

        formatAccountName: function () 
             //do something
        


    );

return LandingView; );

然后还有一个文件InvitationsView.js

define([
    'jquery',
    'underscore',
    'backbone',
    'marionette',
    'views/landing/LandingView',
    'text!templates/invitations/invitationsTemplate.html',
], function ($, _, Backbone, Marionette, LandingView, invitationsTemplate ) 


var InvitationsView = Backbone.View.extend(
        el : $("#invitations"),
        id : 'invitations',
        transition : 'slide',

        initialize : function ()  debugger;

            this.$el.attr('data-transition', this.transition);
            this.currentUserLogin = currentUserLogin;
            var that = this;

        ,
        events : 

        ,
        render : function ()  debugger;
            $('.menu li').removeClass('active');
            $('.menu li a[href="#"]').parent().addClass('active');

            this.GetUserInvitationDetails();

             this.$el.html(invitationsTemplate);

        ,
        cleanup: function()  
            this.undelegateEvents();
            $(this.el).empty();
        ,

        GetUserInvitationDetails: function () 

            var landingView =  new LandingView();
            currentUserName= landingView.formatAccountName();
            curUser = currentUserName.replace("\\", "^").replace("^", "%5E");

            var profilemsg = landingView.GetProfile(currentUserName);

        ,

    );

return InvitationsView;);

现在我需要将第一个 JS 中定义的 formatAccountName 和 GetProfile 函数调用到第二个 JS。我无法做到这一点。我得到错误。 当我尝试

varlandingView = new LandingView(); currentUserName=landingView.formatAccountName();

这也失败了。有人可以在这方面帮助我并告诉我如何实现这一目标

【问题讨论】:

可以显示错误信息吗? 为什么要在一个特定的视图中嵌入一个实用函数?将实用函数收集在库中并将它们拉到需要它们的任何地方会更有意义。如果这样更有意义,您甚至可以将它们设置为 mixins。 【参考方案1】:

您当前调用formatAccountName 方法的方法有效。以下 jsfiddle 显示了这一点:

http://jsfiddle.net/v4h11qac/

这个问题很可能是由于另一个错误没有被正确处理,导致代码没有运行。您应该修复现有的错误,并且方法调用应该按预期工作。

原答案:

您可以直接在原型对象上调用该方法:

LandingView.prototype.formatAccountName();

如果您需要通过新的上下文,您可以使用callapply 方法,如下所示:

LandingView.prototype.formatAccountName.call(context);

更好的方法可能是创建一个可以由两个视图共享的帮助模块。

var viewHelpers = 
    formatAccountName: function(account) 
        // ...
    
;

var ViewOne = Backbone.View.extend(
    render: function() 
        var formattedName = viewHelpers.formatAccountName(this.model);
        // ...
    
;


var ViewTwo = Backbone.View.extend(
    render: function() 
        var formattedName = viewHelpers.formatAccountName(this.model);
        // ...
    
;

您也可以使用系统总线,但是对于这样的用例来说这可能有点太重了。如果您想查看该路径,那么Backbone.Radio 提供了可用于满足此要求的请求/响应模式。

【讨论】:

感谢卡尔的回答。我对此有一个问题,正如我所说的,我的两个视图都在单独的文件中,所以在这种情况下,这种方法会起作用吗?我已经在使用定义来要求所有视图中的所有必需 js。请告知。 是的,只需将辅助模块添加为使用它的模块中的依赖项即可。我还更新了我的答案,包括对原始问题的解释。【参考方案2】:

您可以使用在某种 main-js 文件中声明的全局事件调度程序,如下所示:

var vent = _.extend(, Backbone.Events);

然后在你的视图中,监听一个事件并运行函数。

vent.on('your:event',this.function_to_run_from_other_view,this);

从另一个视图发送这样的事件。

vent.trigger('your:event',args)

【讨论】:

这通常在一个视图需要响应另一个视图的变化时使用,而不是用于访问实用程序功能。您如何从事件中获取 formatAccountName 的返回值? 其实我有这个想法。在这种情况下,没有回报,所以它可能会完成这项工作。但是,如果您有更好的方法(我认为),那就太好了。事实是,我自己也遇到过几次这个问题,但没有以一种足够干净的 IMO 方式解决它。 我的建议在my comment on the question,我现在没有时间充实它。

以上是关于如何从单独文件中的另一个视图调用主干视图函数的主要内容,如果未能解决你的问题,请参考以下文章

如何通过主干中的 ajax 调用使用模型渲染多个视图

快速从单独的视图控制器调用函数

为父级调用渲染的主干子视图

如何从单独的 js 文件中调用角度 $scope 函数? [复制]

将数据从一个视图控制器传递到同一视图上的另一个视图控制器

Swift segue 到函数中的另一个视图控制器