【问题标题】:Backbone View render not being called upon Model change, although bound?模型更改时不调用主干视图渲染,尽管绑定?
【发布时间】:2014-05-24 22:26:30
【问题描述】:

我对 JavaScript 还很陌生,对 Backbone.js 完全陌生。

在下面的代码中,我创建了一个新的 UserLocationModel 并将这个模型实例传递给一个新的 UserLocationView 对象。在此视图的 initialize() 中,我(尝试)将 render() 绑定到传递的模型发生的任何更改。

我相当确定模型发生了变化,我从navigator.geolocation 收到了新的纬度和经度值,并将这些值分配给模型的值。我也知道视图成功接收模型(this.model 永远不会为空)。

为什么没有调用 UserLocationView.render()?

型号:

var UserLocationModel = Backbone.Model.extend({
    defaults: {
        latitude: -1,
        longitude: -1
    },

    updateLocation: function() {
        if(navigator.geolocation){
            navigator.geolocation.getCurrentPosition(this.positionSuccess, this.positionFailure);
                    }
    },

    positionSuccess: function(position) {
        this.set({ 
            latitude : position.coords.latitude,
            longitude : position.coords.longitude
        });
    },

    positionFailure: function() {
        ...
    }
});

查看:

var UserLocationView = Backbone.View.extend({
    initialize: function(){
        _.bindAll(this,'render');
        if(this.model) this.model.on('change',this.render,this);
    },
    render: function(){
        console.log('UserLocationView render called.');
        ...
    }
});

执行开始:

window.MyApp = Backbone.View.extend({

    initialize: function() {
        userLocationModel = new UserLocationModel();
        userLocationView = new UserLocationView({ model: userLocationModel });
        userLocationModel.updateLocation();
        this.render();
    }
});

编辑:

我已经重写了上面的一些代码,包括model.set

编辑 2:moxn 的附加信息。

ma​​in.js:

define(['jquery', 'underscore', 'backbone','template', 'myapp'], function() {
    $(document).ready(function() {
        window.App = new MyApp({ appendTo: $('body') });
    });
});

在 HTML 中被 this 调用:

<script data-main="../static/js/main" src="../static/js/vendor/require.js"></script>

【问题讨论】:

  • 你能把你在Model更改的代码贴出来吗?
  • @DennisRongo 变化发生在 positionSuccess() 中。
  • 您是否尝试过使用:positionSuccess: function(position) { this.set({ latitude : position.coords.latitude, longitude : position.coords.longitude },...
  • @DennisRongo 我有,请查看我的问题的编辑。
  • @Caroline 你在哪里调用 MyApp.initialize?直接或通过new MyApp()

标签: javascript backbone.js


【解决方案1】:

除了使用Dennis Rongo 建议的set 方法外,您还需要确保this 在调用positionSuccess 时是一个模型对象。所以是这样的:

updateLocation: function() {
    if(navigator.geolocation) {
        var self = this;
        navigator.geolocation.getCurrentPosition(function() { self.positionSuccess() },
                                                 function() { self.positionFailure() });
    }
},

【讨论】:

  • 感谢 Lyn,感谢您的帮助,我找到了 underscore.js 的 bind()。
【解决方案2】:

getCurrentPositionthis 的上下文更改为地理位置的上下文。

尝试做类似的事情:

updateLocation: function() {
        if(navigator.geolocation)
            navigator.geolocation.getCurrentPosition(
              this.positionSuccess.call(this), 
              this.positionFailure.call(this));
    }, 

【讨论】:

  • 我明白了。但是,我如何在positionSuccess 中保持对position 的访问权限?
  • positionSuccess 应该仍会收到 Geolocation 传入的参数。
  • 感谢丹尼斯,感谢您的帮助,我找到了 underscore.js 的 bind()。
【解决方案3】:

我确信 Dennis 和 Lyn 的答案也是有效的,只是我无法让它们发挥作用。

起作用的是:

方法 A:

    updateLocation: function() {
        console.log('UserLocationModel.getLocation() called.');
        if(navigator.geolocation){
            navigator.geolocation.getCurrentPosition(_.bind(this.positionSuccess, this));
        }
    },

    positionSuccess: function(position) {
        this.set({ 
            latitude : position.coords.latitude,
            longitude : position.coords.longitude
        });
    },

方法 B:

    //in model
    initialize: function() {
        _.bindAll(this,'positionSuccess');
    },

更具体地说,我使用 underscore.js'_.bind()_.bindAll()

bind() 将函数绑定到对象,这意味着无论何时调用该函数,this 的值都会是该对象。或者,将参数绑定到函数以预先填充它们,也称为部分应用。

您的回答让我明白去Pass correct "this" context to setTimeout callback?寻找并找到确切的答案

【讨论】:

    猜你喜欢
    • 2014-09-18
    • 2023-03-13
    • 1970-01-01
    • 1970-01-01
    • 2013-12-18
    • 1970-01-01
    • 2013-09-11
    • 1970-01-01
    • 2014-11-13
    相关资源
    最近更新 更多