Ember.js ember cli如何从控制器内实例化视图

Ember.js ember cli如何从控制器内实例化视图,ember.js,ember-cli,Ember.js,Ember Cli,我正在构建一个地图单页应用程序。我希望能够向GEOJson数据检索的地图添加或删除对象 其中一些对象将显示为 因此,这些对象不是从模板生成的,而是需要在其他地方实例化。我一直在考虑负责解析GEOJson数据的控制器 到目前为止我做了什么 查看 //app/views/map-popup.js import Ember from 'ember'; export default Ember.View.extend({ templateName: "mapPopup", classNames

我正在构建一个地图单页应用程序。我希望能够向GEOJson数据检索的地图添加或删除对象

其中一些对象将显示为
因此,这些对象不是从模板生成的,而是需要在其他地方实例化。我一直在考虑负责解析GEOJson数据的控制器

到目前为止我做了什么

查看

//app/views/map-popup.js
import Ember from 'ember';

export default Ember.View.extend({
  templateName: "mapPopup",
  classNames: ["map-popup"]
});
模板

// app/templates/map-popup.js
<a class="popup-closer" {{action 'closePopup'}}></a>
<div class="popup-header">{{header}}</div>
<div class="popup-content">{{body}}</div>
我在控制器里想的是这样的:

//app/controllers/map-draw.js
//... some code ...//
var popup = this.get('mapPopup').create({feature: this.sketch});
this.get('popups').pushObject(popup);
popup.addToMap();
//... some more code ...//
//app/controllers/map-draw.js
var popup = this.get('mapPopup').create({feature: this.sketch});
//app/contorllers/map-draw.js
var popup = _this.container.lookup('view:map-popup', { singleton: false });
var ctrl = _this.container.lookup('controller:map-popup', { singleton: false });
popup.set('controller', ctrl);
popup.createElement(); // create the div element
我读过很多关于依赖注入、查找等的书

后者很有希望,但我发现创建一个初始值设定项在单个控制器中注入视图有点过分。你觉得怎么样

编辑:一些人尝试第四种解决方案

我添加了一个初始值设定项:

//app/initializers/map-popup-service.js

export function initialize(container, application ) {
  application.inject( 'controller:map-draw', 'mapPopup', 'view:map-popup' );
}

export default {
  name: 'map-popup-service',
  initialize: initialize
};
在地图绘制控制器中放置断点时:

//app/controllers/map-draw.js
//... some code ...//
var popup = this.get('mapPopup').create({feature: this.sketch});
this.get('popups').pushObject(popup);
popup.addToMap();
//... some more code ...//
//app/controllers/map-draw.js
var popup = this.get('mapPopup').create({feature: this.sketch});
//app/contorllers/map-draw.js
var popup = _this.container.lookup('view:map-popup', { singleton: false });
var ctrl = _this.container.lookup('controller:map-popup', { singleton: false });
popup.set('controller', ctrl);
popup.createElement(); // create the div element
我可以获得弹出窗口(调试器):

我可以创建元素:

但如果我尝试获取视图控制器,它尚未被注入:

我尝试在ma draw控制器中多次调用get('mapPopup'),但我总是得到相同的视图实例(相同的id)

我将尝试在“渲染助手”中查看控制器注入是如何工作的

编辑:阅读ember.js源代码的一些输入

在文件ember.js/packages/ember-application/lib/system/application.js中

现在,每次调用create时,我都会得到视图的一个新实例 但是我还是没有控制器

编辑:在读取渲染辅助对象后 我成功地将地图弹出控制器设置为:

//app/controller/map-draw.js
var popup = MapPopup.create({feature: this.sketch});
var controller = this.container.lookup('controller:map-popup');
controller.setProperties({
  target: this,
  parentController: this
});
popup.set('controller', controller);
现在,我可以从弹出控件调用任何函数,但我一点也不喜欢这样。我希望在我打电话给控制器工厂获取控制器的不同实例之前,有人对ember.js有很好的了解,可以指导我这方面的工作

编辑:我能想出的最佳解决方案

读完这篇文章:

如果要在父视图的上下文之外创建视图(此 可能不被推荐,但它正在发生)您将希望 确保通过容器本身实例化视图

this.container.lookup('view:apple')//将提供 苹果视图

我在源代码中读到:

 /**
    Given a fullName return a corresponding instance.

    The default behaviour is for lookup to return a singleton instance.
    The singleton is scoped to the container, allowing multiple containers
    to all have their own locally scoped singletons.

    ```javascript
    var container = new Container();
    container.register('api:twitter', Twitter);

    var twitter = container.lookup('api:twitter');

    twitter instanceof Twitter; // => true

    // by default the container will return singletons
    var twitter2 = container.lookup('api:twitter');
    twitter2 instanceof Twitter; // => true

    twitter === twitter2; //=> true
    ```

    If singletons are not wanted an optional flag can be provided at lookup.

    ```javascript
    var container = new Container();
    container.register('api:twitter', Twitter);

    var twitter = container.lookup('api:twitter', { singleton: false });
    var twitter2 = container.lookup('api:twitter', { singleton: false });

    twitter === twitter2; //=> false
    ```

    @method lookup
    @param {String} fullName
    @param {Object} options
    @return {any}
  */
  lookup: function(fullName, options)
我最终在我的控制器中完成了以下操作:

//app/controllers/map-draw.js
//... some code ...//
var popup = this.get('mapPopup').create({feature: this.sketch});
this.get('popups').pushObject(popup);
popup.addToMap();
//... some more code ...//
//app/controllers/map-draw.js
var popup = this.get('mapPopup').create({feature: this.sketch});
//app/contorllers/map-draw.js
var popup = _this.container.lookup('view:map-popup', { singleton: false });
var ctrl = _this.container.lookup('controller:map-popup', { singleton: false });
popup.set('controller', ctrl);
popup.createElement(); // create the div element
singleton:false非常重要,如果没有它,所有的弹出窗口都会呈现相同的内容(最后添加的内容)

编辑我发现了关于子视图的内容,今天可能会看一看