1

したがって、アプリケーション内のすべてのビューで要素に対してアクションを実行するための最良の方法は何でしたか。

シングルページ以外のアプリケーションでは、次のように実行します。

$(document).ready(function() { 
    $('.autosize').autosize();
});

すべてのページの autosize クラスを持つすべての要素に autosize 関数を適用します。

Backbone Marionette アプリでこれを行うには、各ビューでonDomRefreshまたは類似のものを実行できますが、ビューの 90% に影響を与えるものについては、これを何らかの方法で自動的に実行する必要があります。

onDomRefreshApplication オブジェクトがそれを解決する可能性のあるすべてのイベントをリッスンできる方法はないと思います。これを追加するためにオーバーロードを検討Marionette.MonitorDOMRefreshしましたが、バックボーンのアプローチのようには感じません。

他に考えたことは、各マリオネット ビューをサブクラス化して、UI 要素のさまざまなグループを読み込むための mixin を追加することでした。

他の人もこのシナリオを経験したにちがいないと考えたので、どのようなアプローチが使用されているかに興味がありました。

4

3 に答える 3

0

そのため、Twitter で @julio_menedez および @marionettejs との有益なチャットにもかかわらず、私の問題を本当に解決する解決策を見つけることができませんでした。Polymerを使用することは非常に良いアイデアでしたが、古い IE をサポートする必要があるため適切ではありませんでした。

その代わりに、私はそれを解決するためにモンキー パッチの危険な世界に向かいました (これはまだ書き終わったばかりで、完全にはテストされていないため、いくつかのしわを修正する必要があるかもしれないことを覚えておいてください。それに応じて更新します)

Coffeescript の場合: (一番下の JavaScript バージョン)

# Monkey patching the Marionette View.. sorry!

# this is the only Marionette view which doesn't have it's own constructor
Marionette.ItemView = Marionette.ItemView.extend
  constructor: ->
    Marionette.View.prototype.constructor.apply @, Array.prototype.slice.call(arguments, 0)

original_view_constructor = Marionette.View.prototype.constructor
Marionette.View.EventAggregator = event_aggregator = _.extend {}, Backbone.Events

# all the other constructors call this so we can hijack it
Marionette.View.prototype.constructor = ->
  event_aggregator.listenTo @, 'all', =>
    args_array = Array.prototype.slice.call arguments, 0
    event_aggregator.trigger.apply event_aggregator, [ 'view:' + args_array[0], @ ].concat(args_array.slice(1))
    event_aggregator.stopListening @ if args_array[0] == 'close'
  original_view_constructor.apply @, Array.prototype.slice.call(arguments, 0)

次に、必要なビュー イベントをキャッチするために、アプリケーション オブジェクトにリスナーを設定するだけです。例えば:

@listenTo Marionette.View.EventAggregator, 'view:dom:refresh', (view) ->
  view.$('div').css('backgroundColor', 'red');

したがって、私の見解では、これらはこの手法の長所と短所です。

長所:

  • すべてのビュー クラスを注入したり、すべてのビュー クラスをサブクラス化したりすることなく、すべてのビュー イベントをリッスンできます。
  • 使い方は簡単
  • オブジェクトは、それを使用するためにオプトインする必要はまったくありません

短所

  • Marionette にとって危険なモンキー パッチを使用 API の変更
  • Marionette 名前空間を使用するため、将来の Marionette 名前空間の衝突に対して脆弱です
  • ビューのコンテキスト外でビューを処理する
  • イベントアグリゲーターオブジェクトを持つことは、Backbone/Marionette (afaiw) の他の場所で見られるものではないため、パターンを壊します (更新 - Backbone.history で同様のことが見られます)。

とにかく、フィードバック、代替案、批判を歓迎します:-)そして、これが同じ状況の他の誰かに役立つことを願っています

Javascript:

(function() {
  var event_aggregator, original_view_constructor;

  Marionette.ItemView = Marionette.ItemView.extend({
    constructor: function() {
      return Marionette.View.prototype.constructor.apply(this, Array.prototype.slice.call(arguments, 0));
    }
  });

  original_view_constructor = Marionette.View.prototype.constructor;

  Marionette.View.EventAggregator = event_aggregator = _.extend({}, Backbone.Events);

  Marionette.View.prototype.constructor = function() {
    var _this = this;
    event_aggregator.listenTo(this, 'all', function() {
      var args_array;
      args_array = Array.prototype.slice.call(arguments, 0);
      event_aggregator.trigger.apply(event_aggregator, ['view:' + args_array[0], _this].concat(args_array.slice(1)));
      if (args_array[0] === 'close') {
        return event_aggregator.stopListening(_this);
      }
    });
    return original_view_constructor.apply(this, Array.prototype.slice.call(arguments, 0));
  };

}).call(this);
于 2013-08-19T12:41:00.817 に答える
0

基本ビュー クラスを作成し、自動サイズ拡張が必要な​​すべてのビュー クラスを継承するだけです。

var AutosizeBaseView = Backbone.Marionette.ItemView.extend({
    onDomRefresh: function(){
        this.$('.autosize').autosize();
    }
});

次に、クラスを次のようにします。

var SomeView = AutosizeBaseView.extend({
});
于 2013-08-15T15:41:50.653 に答える
0

CoffeeScript では、次のこともできると思います。

extend = (obj, mixin) ->
  obj[name] = method for name, method of mixin        
  obj

include = (klass, mixin) ->
  extend klass.prototype, mixin

include Marionette.View,
  onDomRefresh: () -> @$('.autosize').autosize()

すべてのビュータイプをカバーする必要があります。これを具体的にテストしたわけではありませんが、Marionette のレイアウト ビューに機能を追加するために非常によく似た操作を行っただけです。http://arcturo.github.io/library/coffeescript/03_classes.htmlでパターンを拡張/インクルードします。もちろん、これはすべてストレート JS でも実行できるはずです。

アップデート:

include実際には、Underscore を使用できるので、 andextendメソッドを手動で定義する必要はありません。次のように言えます。

_.extend Marionette.View.prototype,
  onDomRefresh: () -> @$('.autosize').autosize()
于 2013-12-14T16:11:44.273 に答える