【问题标题】:Integrating JSON feed with Backbone JS将 JSON 提要与 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 而言。谢谢。

标签: javascript jquery 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 上与我联系以解决问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-12-30
    • 2021-12-16
    • 2019-12-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-05-09
    相关资源
    最近更新 更多