将 JSON 提要与 Backbone JS 集成

Posted

技术标签:

【中文标题】将 JSON 提要与 Backbone JS 集成【英文标题】:Integrating JSON feed with Backbone JS 【发布时间】:2011-08-03 13:14:25 【问题描述】:

我目前正在做一个项目,我在输入框中键入一个关键字,当我点击发送时,它会通过一个链接访问 php 服务器,例如 (localhost/json-status.php?query=input text ) 并以 json 格式返回 "query=" 之后的任何内容。现在我已经用 jQuery 完成了这项工作,我正在尝试在骨干 js 中再次这样做。

$("#updateStatus").click(function()

   var query = $("#statusBar").val();

   var url = "json-status.php" + "?query=" + query;

   $.getJSON(url,function(json)
            $.each(json.posts,function(i,post)
         $("#content").append(
            '<div>'+
               '<p>'+post.status+'</p>'+
            '</div>'
         );
      );
   );
);

我几乎已经将我在 jQuery 中所做的事情移植到了主干 js,但到目前为止它并没有按预期工作,请告诉我我的方法是否正确以及如何解决我的问题。

主干代码:

(function ($) 
   Status = Backbone.Model.extend(
      status: null
   );

   StatusList = Backbone.Collection.extend(
      initialize: function (models, options) 
         this.bind("add", options.view.addStatusList);
      
   );

   AppView = Backbone.View.extend(
      el: $("body"),
      initialize: function () 
         this.status = new StatusList( null,  view: this );
      ,
      events: 
         "click #updateStatus":   "getStatus",
      ,
      getStatus: function () 
         var url = "json-status.php" + "?query=" + $("#statusBar").val();
         var statusModel;

         $.getJSON(url,function(json)
            $.each(json.posts,function(i,post)
               statusModel = new Status( status: post.status );
               this.status.add( statusModel );
            );
         );
      ,
      addStatusList: function (model) 
         $("#status").prepend("<div>" + model.get('status') + "</div>");
      
   );

   var appview = new AppView;
)(jQuery);

以 json 格式返回的 PHP 服务器代码(这工作正常):

<?php
    $getQuery = $HTTP_GET_VARS["query"];

    $json='
    "posts":[
        
            "status": "' . $getQuery . '"
        
    ]
    ';
    echo $json;
?>

如果你想复制/粘贴我到目前为止的内容:

<!DOCTYPE html>
<html>
<head>
    <title>JSON Test</title>
</head>
<body>

    <input value="What's on your mind?" id="statusBar" /><button id="updateStatus">Update Status</button>

    <div id="content">

    </div>

    <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.min.js"></script>
    <script src="http://ajax.cdnjs.com/ajax/libs/underscore.js/1.1.4/underscore-min.js"></script>
    <script src="http://ajax.cdnjs.com/ajax/libs/backbone.js/0.3.3/backbone-min.js"></script>

    <script type="text/javascript">
        $("#statusBar").click(function() 
            $(this).val("");
        );

        (function ($) 
            Status = Backbone.Model.extend(
                status: null
            );

            StatusList = Backbone.Collection.extend(
                initialize: function (models, options) 
                    this.bind("add", options.view.addStatusList);
                
            );

            AppView = Backbone.View.extend(
                el: $("body"),
                initialize: function () 
                    this.status = new StatusList( null,  view: this );
                ,
                events: 
                    "click #updateStatus":  "getStatus",
                ,
                getStatus: function () 
                    var url = "json-status.php" + "?query=" + $("#statusBar").val();
                    var statusModel;

                    $.getJSON(url,function(json)
                        $.each(json.posts,function(i,post)
                            statusModel = new Status( status: post.status );
                            this.status.add( statusModel );
                        );
                    );
                ,
                addStatusList: function (model) 
                    $("#status").prepend("<div>" + model.get('status') + "</div>");
                
            );

            var appview = new AppView;
        )(jQuery);
    </script>

</body>
</html>

感谢您的宝贵时间。


朱利安的密码。

StatusList = Backbone.Collection.extend(
    model: Status,
    value: null,
    url: function() return "json-status.php?query=" + this.value;
);

AppView = Backbone.View.extend(
    el: $("body"),
    initialize: function () 
        _.bindAll(this, "render");// to solve the this issue
        this.status = new StatusList( null,  view: this );
        this.status.bind("refresh", this.render);
    ,
    events: 
        "click #updateStatus" :"getStatus",
    ,
    getStatus: function () 
        this.status.value =  $("#statusBar").val();
        this.status.fetch(this.status.value);
    ,
    render: function () 
        var statusEl = $("#status");
        this.status.each( function(model) 
            statusEl.prepend("<div>" + model.get('status') + "</div>");
        );
    
);

var appview = new AppView;

完整的 HTML(第 2 部分):

<!DOCTYPE html>
    <html>
    <head>
        <title>JSON Test</title>
    </head>
    <body>

        <input value="What's on your mind?" id="statusBar" />
        <button id="updateStatus">Update Status</button>

        <div id="status">

        </div>

        <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.min.js"></script>
        <script src="http://ajax.cdnjs.com/ajax/libs/underscore.js/1.1.4/underscore-min.js"></script>
        <script src="http://ajax.cdnjs.com/ajax/libs/backbone.js/0.3.3/backbone-min.js"></script>

        <script type="text/javascript">
            $("#statusBar").click(function() 
                $(this).val("");
            );

            Status = Backbone.Model.extend();

            StatusList = Backbone.Collection.extend(
                model: Status,
                value: null,
                url: function() return "json-status.php?query=" + this.value;
            );

            AppView = Backbone.View.extend(
                el: $("body"),
                initialize: function () 
                    _.bindAll(this, "render");// to solve the this issue
                    this.status = new StatusList( null,  view: this );
                    this.status.bind("refresh", this.render);
                ,
                events: 
                    "click #updateStatus" :"getStatus",
                ,
                getStatus: function () 
                    this.status.value =  $("#statusBar").val();
                    this.status.fetch(this.status.value);
                ,
                render: function () 
                    var statusEl = $("#status");
                    this.status.each( function(model) 
                        statusEl.prepend("<div>" + model.get('status') + "</div>");
                    );
                
            );

            var appview = new AppView;

        </script>

    </body>
    </html>

PHP 与最初记录的 PHP 相同。

【问题讨论】:

问题到底出在哪里? 我相信问题出在这里:$.each(json.posts,function(i,post) statusModel = new Status( status: post.status ); this.status.add( statusModel ); ); 它能够很好地加载帖子的数量,但我无法将其添加到 addStatusList。我相信它可能是 this.status.add(statusModel) 中的“this”,但我不是 100% 确定。 好吧,这不是你的观点。它是 jquery 的绑定。在您的 getJSON 之外,执行 var self = this 然后执行 self.status.add(statusModel); 太棒了!那解决了它。我还发现我的 addStatusList 函数中有一个错误,它将 prepend 应用于一个不存在的容器。谢谢你。我将在答案中发布完整的 HTML 以供进一步参考。但是在我走之前最后一个问题,我这样做正确吗?就将 JSON 导入到backbone.js 而言。谢谢。 【参考方案1】:

仅供参考 (来自文档)

我们借此机会澄清了 0.5.0 版本的一些命名。控制器现在是路由器,现在已重置刷新

因此,如果您使用的是最新版本,请不要忘记在此行中将 refresh 更改为 reset

this.status.bind("refresh", this.render);

【讨论】:

【参考方案2】:

至于您的一般设计,您应该使用Backbone.ModelCollection 来获取您的状态:

Status = Backbone.Model.extend();

StatusList = Backbone.Collection.extend(
  model: Status,
  value: null
  url: function() return "json-status.php" + "?query=" + this.value;
);

您的视图应该监听 StatusList 而不是 StatusList 创建与视图的绑定:

AppView = Backbone.View.extend(
  el: $("body"),
  initialize: function () 
    _.bindAll(this, "render");// to solve the this issue
    this.status = new StatusList( null,  view: this );
    this.status.bind("refresh", this.render);
  ,
  events: 
    "click #updateStatus":  "getStatus",
  ,
  getStatus: function () 
    this.status.value =  $("#statusBar").val();
    this.status.fetch()
  ,
  render: function () 
    var statusEl = $("#status")
    this.status.each( function(model)
      statusEl.prepend("<div>" + model.get('status') + "</div>");
    
  
);

这里有几件事:

模型上的属性是由 set/get 定义的,而不是像你对 status 所做的那样由 js 属性定义 尝试将视图了解模型但模型不了解视图的内容解耦

【讨论】:

啊,这就是我要找的。我感觉使用 $.getJSON 不是将 JSON 导入主干的正确方法。这让事情变得很清楚,谢谢。现在我尝试实现你的代码,但我遇到了几个问题,我已经继续并修复了我认为的所有语法错误,但截至目前,每当点击 updateStatus 按钮时,model.get( 'status') 返回未定义。我附上了您的代码的无语法错误版本 + 我的完整代码 + 在我最初的问题中运行的 php。感谢您的宝贵时间。 没关系,我想通了。原来是 PHP 出了问题。 离题... Julien,很快感谢您在 SO 上发布关于 Backbone 的所有帖子。真的很有帮助! 我是来帮忙的。您也可以通过 julien.guimont@gmail.com 在 gtalk 上与我联系以解决问题。

以上是关于将 JSON 提要与 Backbone JS 集成的主要内容,如果未能解决你的问题,请参考以下文章

Node.js 与 CouchDB 和 Backbone.js 一起使用,如何提供 json?

如何将骨干js与一些传统插件一起使用?

Backbone.js:为 Backbone.sync 实现定义超时

Backbone.js + Handlebars 各

如何将backbone.js 与websockets/socket-io/nowjs 一起使用

将 Facebook 的提要列表与图形 api 集成时的问题