0

Ember では、テンプレート内で多くのビュー ヘルパーを使用しています。ヘルパーが実行されているとき (View が作成されているとき) に mixin を Ember.View クラスに渡す簡単な方法があるかどうか疑問に思っていました。

http://jsbin.com/ekuxal/2/editのようなもの

テンプレートの例:

{{view Ember.TextField mixins="App.Console"}}

ミックスインの例:

App.Console = Ember.Mixin.create({
   didInsertElement: function(){
     this._super();
     console.log('from the mixin');
   }
});

ミックスインからコンソールにログインします。

そのようなものを持っていることは意味がありますか?

ありがとう

4

2 に答える 2

0

私の観点からは、この要件は私には意味がありません。なんで?ミックスインは、多重継承を実現する方法であるため、クラスを拡張するときに使用されます。したがって、これらはデータおよびロジックモデリング中に使用されます。また、ビューヘルパーは、ビュークラスのオブジェクトをインスタンス化するために使用されます。カスタムヘルパーを作成し、その中でcreateWithMixins()を使用することで実現できると思います。しかし、テンプレートでそのようなことを行うのは混乱しているようです。

要件をもう少し明確にできますか?それは本当にロギングについてですか?

更新:実装提案

ビューヘルパーのソースコードを読んで、これが可能かどうかを評価します。これはEmberのすぐに使用できる機能ではありませんが、EmberViewヘルパーの一部のロジックを上書きすることで可能になる場合があります。

このテンプレートがあると仮定します。

{{view App.YourView mixin="App.YourMixin"}}

ヘルパーにとって最も重要なのは、変更するロジックを含むインスタンスEmber.ViewHelperです。それを再び開いて、次のように関連する部分を変更することを試みることができます:

var EmberHandlebars = Ember.Handlebars;
EmberHandlebars.ViewHelper.reopen({
  helper: function(thisContext, path, options) {
    var inverse = options.inverse,
        data = options.data,
        view = data.view,
        fn = options.fn,
        hash = options.hash,
        newView;

    if ('string' === typeof path) {
      newView = EmberHandlebars.get(thisContext, path, options);
      Ember.assert("Unable to find view at path '" + path + "'", !!newView);
    } else {
      newView = path;
    }

    // NEW CODE FOR MIXIN LOGIC
    if(hash.mixin){
      var newViewClass = newView; // newView should be the class App.YourView here
      var yourMixin = Ember.get(hash.mixin); //get the Mixin by name
      var newViewInstance = newView.createWithMixins(yourMixin); //create the view with mixin
      newView = newViewInstance; // assign the view to the variable where the rest of the logic is expecting it
    }

    Ember.assert(Ember.String.fmt('You must pass a view to the #view helper, not %@ (%@)', [path, newView]), Ember.View.detect(newView) || Ember.View.detectInstance(newView));

    var viewOptions = this.propertiesFromHTMLOptions(options, thisContext);
    var currentView = data.view;
    viewOptions.templateData = options.data;
    var newViewProto = newView.proto ? newView.proto() : newView;

    if (fn) {
      Ember.assert("You cannot provide a template block if you also specified a templateName", !get(viewOptions, 'templateName') && !get(newViewProto, 'templateName'));
      viewOptions.template = fn;
    }

    // We only want to override the `_context` computed property if there is
    // no specified controller. See View#_context for more information.
    if (!newViewProto.controller && !newViewProto.controllerBinding && !viewOptions.controller && !viewOptions.controllerBinding) {
      viewOptions._context = thisContext;
    }

    currentView.appendChild(newView, viewOptions);
  } 
});

注:このロジックを自分でテストすることはまだできませんでした。 更新:正常にテストされました!

于 2013-03-15T08:01:19.940 に答える