Muszę użyć zmiennej guid w funkcji render(), ale mogę przekazać go tylko do konstruktora. I Ten kod:

app.views.CompanyView = Backbone.View.extend({
    el: '#company-view',
    guid: '',

    initialize: function (options) {
        this.guid = options.guid;
    },

    render: function () {
        var guid = this.guid;
    }
});

Uważam mój widok w ten sposób:

app.currentView = new app.views.CompanyView({guid: guid});

Następnie przekazuję funkcję render() jako parametr, aby użyć go jako wywołania zwrotnego:

function call(callback){
    callback();
}

call(app.currentView.render);

Próbowałem this.guid, options i this.options też, ale wszystkie były undefined. Czy istnieje sposób, aby przekazać tę zmienną funkcji render() bez użycia jego argumentów lub zmiennych globalnych? Oto JSFiddle Przykład.

1
totymedli 25 listopad 2013, 20:51

2 odpowiedzi

Najlepsza odpowiedź

Kiedy zadzwonisz render przez to:

function call(callback){
    callback();
}

Dzwonisz do tego jako zwykłą funkcję, więc this wewnątrz render będzie window. Pamiętaj, że this w JavaScript zależy od tego, jak nazywa się funkcja, a nie jak jest zdefiniowany (chyba że oczywiście grasz z funkcjami związanymi).

Masz kilka opcji:

  1. Bind render do widoku za pomocą _.bindAll, _.bind, $.proxy { {X4}}, ...

    initialize: function() {
        _.bindAll(this, 'render');
    }
    

    DEMO: http://jsfiddle.net/ammigious/gsufy/

  2. Bardziej powszechne podejście jest obecnie przekazanie kontekstu z funkcją, a następnie ktokolwiek wywołuje zwrotny wykorzystuje odpowiedni kontekst za pomocą call lub apply:

    function call(callback, context){
        callback.apply(context);
    }
    

    Demo: http://jsfiddle.net/ammiguous/lnWPR/

  3. Zrób to sam?

    call(function() { v.render() });
    

    Ten zwykle ma formę var _this = this;, a następnie anonimową funkcją używa _this.some_method() zamiast tylko przekazywania this.some_method jako wywołanie zwrotne.

    DEMO: http://jsfiddle.net/amGigious/k2xj4/

Wolę drugą opcję.

2
mu is too short 25 listopad 2013, 17:41

Widzę. Gdy twoja render () jest wywoływana przez funkcję wywołania zwrotnego, rozmówca metody nie jest już widokiem, więc "to" wewnątrz renderowania będzie dzwoniącego funkcji połączenia ().

Zobacz to skrzypce:

http://jsfiddle.net/cn8nn/2/

var CompanyView = Backbone.View.extend({
  initialize: function (options) {
      this.guid = options.guid;
  },

  render: function () {
    console.log('hello');
    console.log(this);
  }
});

var v = new CompanyView({guid: 'the guid'});

function call(callbcak) {
  callbcak();
}

call(v.render);

Jeśli otworzysz konsolę, zobaczysz "To" jest w rzeczywistości oknem.

Aby obejść to wokół tego, chcesz nawiązać kontekst do samego siebie.

Aby to zrobić, użyj _.Bindall ();

initialize: function (options) {
    _.bindAll(this, "render");
    this.guid = options.guid;
}

Jsfiddle: http://jsfiddle.net/cn8nn/3/

2
Yurui Zhang 25 listopad 2013, 17:38