2016-11-10 11 views
0

Gruntを私のビルドツールとしてWebpackに切り替えました。移行はであり、比較的であった。少なくとも私が次の問題を抱えていることに気づくまでは、それはありました。サブビュー変更イベントが起動しない

私は現在、アプリケーションに多くのバックボーンビューを持っており、私が移動すると、ファクトリメソッドを使用してインスタンス化し、ガベージコレクションを行っています。私のサブビューのうちの1つであるchangeのイベントはもはや発砲していません(つまり、以前は発砲していたので、ある時点で動作していました)。ユーザーは、ループの中で親ビューに入るときにサブビューが生成されます。

for (var i=0; i<this.dayIds.length; i++) { 
    this.timeSelectorDayViews[i] = new timeSelectorDay({ 
    el: '#timePickersWrapper', 
    data: { 
     time: this.model.get(this.dayIds[i]), 
     date: moment(this.model.get('weekStartDate')).add(i, 'd') 
    } 
    }).render(); 
} 

そしてここでは、サブビューコードです:

'use strict'; 

import { app } from '../app'; 

export const timeSelectorDay = Backbone.View.extend({ 
    initialize: function(data) { 
     this.options = data; 
     this.options.data.formattedDate = moment(this.options.data.date).format('YYYY-MM-DD'); 
     this.events = _.clone(this.events) || {}; 
     var inputEventKey = 'change' + ' .input-' + this.options.data.formattedDate; 
     this.events[inputEventKey] = 'inputCheck'; 
     this.totalHours = 0; 
    }, 
    render: function(){ 
     this.template = _.template(app.createTemplate('templates/timeSelectorDay.tpl', this.options.data)); 
     $(this.options.el).append(this.template({})); 
     this.delegateEvents(); 
     this.checkTotalTime(); 
     return this; 
    }, 
    inputCheck: function() { 
     ... 
     ... //Doing some computational logic here 
     ... 
     app.event_bus.trigger('totalTime'); 
     app.event_bus.trigger('inputChange'); 
    }, 
    checkTotalTime: function(){ 
     var totalTimeDiv = document.getElementById('totalHours-'+this.options.data.formattedDate); 
     var totalTime = parseFloat(totalTimeDiv.innerHTML); 
     if (totalTime>0) { 
     totalTimeDiv.style.backgroundColor = '#69a776'; 
     } else { 
     totalTimeDiv.style.backgroundColor = '#dd3c3c'; 
     } 
     this.totalHours = totalTime; 
    } 
}); 

それはまた、私はイベントを生成してることは注目に値するのものであってもよいです文字列の連結とイベント配列の変更を介して非正常なバックボーンのやり方で。なぜなら、HTML要素にユニークなIDを割り当てる必要があるからです。

私の最初の考えは、イベントが正しく接続されていない何らかの理由で、新しいwebpackの実装が多分あったということでした。私はthis.delegateEvents()を呼び出すことでこれを解決しようとしましたが、成功しませんでした。

私の次の考えは、イベントがビュースコープから外れているか何らかの理由で切り離されている可能性があるため、input要素がイベント内でイベントにアタッチ可能であることを確認しました。また、問題ではありません。

var inputEventKey = 'click' + ' .input-' + this.options.data.formattedDate; 

はUPDATE(追加データ):

私はそれが完全に正常に動作し、対応する機能を起動 clickイベントにその changeイベントを変更した場合

私はこのような状況についての最も不可解だ何だと思うです

サブビューテンプレート:

<div id="timeselectors-<%= formattedDate%>" class="row small-collapse medium-uncollapse margin-bottom border"> 
    <div class="small-12 columns"><%= moment(date).format('dddd') %> (<%= moment(date).format('MM/DD/YYYY') %>)</div> 
    <div class="small-10 columns"> 
    <div class="row small-collapse"> 
     <div class="small-5 medium-2 columns morning"> 
     <input id="morning-login" class="input-<%= formattedDate%>" type="text" id="example" placeholder="Login"/> 
     </div> 
     <div class="small-1 medium-1 columns morning dash"> - </div> 
     <div class="small-5 medium-2 columns morning"> 
     <input id="morning-logout" class="input-<%= formattedDate%>" type="text" id="example" placeholder="Logout"/> 
     </div> 
     <div class="small-5 medium-2 medium-offset-1 columns afternoon"> 
     <input id="afternoon-login" class="input-<%= formattedDate%>" type="text" id="example" placeholder="Login"/> 
     </div> 
     <div class="small-1 medium-1 columns afternoon dash"> - </div> 
     <div class="small-5 medium-2 columns afternoon end"> 
     <input id="afternoon-logout" class="input-<%= formattedDate%>" type="text" id="example" placeholder="Logout"/> 
     </div> 
    </div> 
    </div> 
    <div id="totalHours-<%= formattedDate%>" class="small-2 columns hours"> 
    <%= time %> 
    </div> 
</div> 

私のWebPACKの設定に関しては、私は私のWebPACKのドライバとしてがぶ飲みを使用していますが、ここで設定です私はあなたがダウンしてクローンを作成したい場合は、すべてのコードはgithubの上で公開されていることを述べてきたはずですそのすべてに加えて

// import 'babel-polyfill'; 
import 'script!jquery'; 
import 'script!lodash'; 
// import 'script!what-input'; 
import Backbone from 'backbone'; 
import 'backbone-validation'; 
import 'script!jquery.cookie'; 
import 'script!moment'; 
import 'script!fastclick'; 
import 'script!clndr'; 
import 'script!timepicker'; 
import 'script!foundation-sites/js/foundation'; 

import { app } from './app'; 

$(document).ready(function() { 
    app.init(); 

    //Initialize Foundation 
    $(document).foundation(); 
}); 

{ 
    entry: './src/app/client-app/index.js', 
    output: { 
    path: path.join(__dirname, 'dist/app/js'), 
    filename: 'app.bundle.js' 
    }, 
    plugins: [ 
    new webpack.ProvidePlugin({ 
     '_': 'lodash' 
    }) 
    ], 
    module: { 
    loaders: [ 
     {test: /\.js$/, exclude: /node_modules/, loaders: ['babel'] }, 
    ] 
    } 
} 

WebPACKのエントリファイル:私はWebPACKのインスタンスに渡しますレポと問題を再現:

https://github.com/wootencl/timeSheetApplication/tree/ProjectRewrite

UPDATE(11/14/16):unsuccesfully制御以内にこれを複製しようとした後、 (plunkrなど)私は徐々に問題を診断するために後方に働き始めることにしました。これまでのところ、問題はwebpackからではなく、プロジェクトのモジュール化から発生していることがわかりました。ファイルごとにbrashスクリプトタグからルートindex.jsに移動し、すべての依存モジュールがインポートされましたが、これは問題が起こり始めるようです。

+0

テンプレートやwebpackの設定や[mcve]がなければ、問題を特定できません。 –

+1

クイック返信ありがとうございました@EmileBergeron!私のファイルを変更して、あなたの推薦を反映させて報告してください。 – wootencl

答えて

1

私は提供されたコードで問題を見つけることはできませんが、改善できる点をいくつか指摘することができます。

開始するには、カスタムオプションを直接渡します。ネストされたdataオブジェクトは必要ありません。バックボーンが提供elとコールsetElementを作成する前に

this.timeSelectorDayViews[i] = new timeSelectorDay({ 
    el: '#timePickersWrapper', 
    time: this.model.get(this.dayIds[i]), 
    date: moment(this.model.get('weekStartDate')).add(i, 'd') 
}).render(); 

は、サブビューで、Iは、コンストラクタにevents変更を移動します。

export const timeSelectorDay = Backbone.View.extend({ 
    // The template should be compiled once here, then used in the render function. 
    template: _.template(app.createTemplate('templates/timeSelectorDay.tpl')), 

    constructor: function(options) { 
     this.options = _.extend({ 
      /* default options could go here */ 
     }, options); // make a copy and use it. 
     this.options.formattedDate = moment(this.options.date).format('YYYY-MM-DD'); 

     // change the events hash before delegating the events. 
     // the constructor is a good place for this. 
     this.events['change .input-' + this.options.formattedDate] = 'inputCheck'; 

     Backbone.View.prototype.constructor.apply(this, arguments); 
    }, 

    initialize: function(options) { 
     this.totalHours = 0; 
    }, 
    render: function() { 
     // use the $el directly, avoid global jQuery. 
     this.$el.html(this.template(this.options)); 
     this.checkTotalTime(); 
     return this; 
    }, 
    inputCheck: function() { 
     // Doing some computational logic here 
     // ...snip... 
     app.event_bus.trigger('totalTime'); 
     app.event_bus.trigger('inputChange'); 
    }, 
    checkTotalTime: function() { 
     // use Backbone's jQuery shortcut instead of the Javascript native 
     // api, it's easier and it is scoped to the view's el. 
     var totalTimeDiv = this.$('#totalHours-' + this.options.formattedDate), 
      totalTime = parseFloat(totalTimeDiv.html()); 
     // I would avoid changing the css in favor of toggling a class. 
     // It would keep the style separated from the logic. 
     totalTimeDiv.css('background-color', totalTime > 0 ? '#69a776' : '#dd3c3c'); 
     this.totalHours = totalTime; 
    } 
}); 
+1

この方法ではまだ幸運にも幸いです。私の見解をきれいにするあなたの提案は、うまくいけば私を正しい方向に向けることができると思う。私の発見と一緒に今夜/明日後に報告します。助けてくれてありがとう! – wootencl

+1

@wootencl助けてくれることは喜ばしいことです;)もう一つの質問です。本当にwebpackに関係していますか?関連するビュー/テンプレートのみを取り出し、実行可能なスニペットを最小限にするとどうなりますか? –

+1

良い質問です。グランツからウェブパックに移行したときに問題に気付き始めたので、それはウェブパックであると仮定しましたが、そうではないかもしれません。もし私が今夜それを理解できないなら、おそらくplunkr(または同様のもの)を作成し、問題を再現できるかどうかを試してみるでしょう。 – wootencl

関連する問題