牵线木偶控制器对象,创建动态原型方法?

时间:2015-04-25 07:18:31

标签: javascript backbone.js prototype marionette

我正在使用牵线木偶作为一个有很多页面的应用程序。控制器/路由器方法是重复的,在每种方法中实例化视图,appRegion显示视图。

我想在循环中创建方法。

var Controller = Marionette.Controller.extend({});

for(i=0;i<10;i++) {
  // build dynamic controller methods
}

我一直在学习对象原型,我想我可以做类似的事情。

var pages = [{'pageButtons': Buttons},{'pageLogin': Login}];
for(var page in pages) {
  for(var method in pages[page]) {
    console.log(method) // write dynamic method here?
  }
}

我的问题是上面的块,如何完成它,我可以在循环中添加新方法吗?有没有办法简化重复添加相同代码的重复任务?

3 个答案:

答案 0 :(得分:2)

我认为你完全走上正轨。我也想,这里实际上有两个问题。您概述了第一个,第二个是动态创建和提供路由到Router

设置Controller查看方法和路由器

我正在考虑像这样修改您的参考pages对象:

var pages = [
  {'pageButtons': Buttons, route: 'buttons'},
  {'pageLogin': Login, route: 'login'}
];

接下来,我们声明控制器并添加动态方法

var Controller = Marionette.Controller.extend({}),
    Router = Marionette.AppRouter.extend({});

for(var page in pages) {
  for(var method in pages[page]) {
    // Each method will be have a pointer in
    // Controller.pagemethod, e.g. Controller.pageButtonsButtons
    Controller[page + method] = pages[page][method];
    // And now we set up the Router
    // e.g. a url of http://appdomain#pagesButton will map to 
    // a method with name 'pageButtonsButtons'
    Router[page] = page + method;
  }
}

当然,天空是您自定义“方法工厂”的限制。您在引用pages对象中添加的属性越多,您的工厂就越具体。

我还想注意,这里我们没有将方法添加到Controller的原型中,只是为了简单起见。而且我认为我们可以在这里使用它,因为通常Controller被实例化一次,我们不一定需要延长原型的生产率。但是,如果你这样做,则没有功能差异。

答案 1 :(得分:0)

如果您的目标是在对象中定义页面设置,然后动态生成路由和控制器功能,请考虑以下事项:

p

jsfiddle让你玩。 http://jsfiddle.net/RyanTanZH/vts85znw/8/

答案 2 :(得分:0)

另一种方法是使用函数来保存您的常用操作。

var app = new Backbone.Marionette.Application();

app.addRegions({
  mainRegion: "#main"
});

// Sample custom view
var view = Marionette.ItemView.extend({custom: 'properties'});

// Main config object
var pages = {
    "page/a": {view: view, msg: "route a!", controllerFunc: "pageA", templateSelector: "#pageA"},
    "page/b": {view: view, msg: "route b!", controllerFunc: "pageB", templateSelector: "#pageB"},
    "page/c": {view: view, msg: "route c!", controllerFunc: "pageC", templateSelector: "#pageC"}
};

// Marionette.Controller is deprecated, just use a plain js object.
var controller = {
    baseAction: function (config){

        // View options
        var viewOptions = {template: config.templateSelector};

        // Instantiate a new view based on the template selector
        app.mainRegion.show(new (config.view)(viewOptions));

        // A log to check the values
        console.log('config = ', config);
    }
}; 
var routes = {};

// Populate controller and routes via routeConfigs
_.each(pages, function (page, route, list){

    // Return a function
    controller[page.controllerFunc] = (function(page){

      // An IIFE, read more on http://en.wikipedia.org/wiki/Immediately-invoked_function_expression
      return function() {
        controller.baseAction(page);
      };
    })(page);

    // Populate routes too
    routes[route] = page.controllerFunc;
});

// The actual appRouter
var router = new Marionette.AppRouter({
  controller: controller,
  appRoutes: routes
});

app.start();
Backbone.history.start();

// Test route A
Backbone.history.navigate('page/a', true);

jsfiddle:http://jsfiddle.net/RyanTanZH/crbdu51w/1/