Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/jquery/69.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 带间隔的淘汰Ajax只显示更改的数据_Javascript_Jquery_Ajax_Knockout.js - Fatal编程技术网

Javascript 带间隔的淘汰Ajax只显示更改的数据

Javascript 带间隔的淘汰Ajax只显示更改的数据,javascript,jquery,ajax,knockout.js,Javascript,Jquery,Ajax,Knockout.js,我有以下代码: function MyViewModel() { var myviewmodel=this; myviewmodel.ajaxData=ko.observableArray([]); myviewmodel.init=function() { updateInterval(function() { myviewmodel.getData(); },6000); } myviewmodel.getData=funct

我有以下代码:

function MyViewModel()
{
  var myviewmodel=this;
  myviewmodel.ajaxData=ko.observableArray([]);


  myviewmodel.init=function()
  {
    updateInterval(function()
    {
      myviewmodel.getData();
    },6000);
  }

  myviewmodel.getData=function()
  {
    myviewmodel.ajaxData([])
    $.get('getData.php')
    .done(function(data)
    {
      if(data.status==='ok' && data.data)
      {
        $.map(data.data,function(f)
        {
          var last_item=new AjaxItem(f);
          myviewmodel.ajaxData.push(last_item);
        })
      }
    })
  }

  function AjaxItem(data)
  {
    var item=this;
    item.id=parseInt(data.id);
    item.name=ko.observable(data.name);
    item.surname=ko.observable(data.surname);
    item.viewed=ko.observable(true);

    setTimeout(function()
    {
       item.viewed(false);
    },600);
  }
}
var vm= new MyViewModel();
ko.applyBindings(vm)
vm.init();
我在这个html中查看它

<!doctype html>
<html>
<head>
........
<script src="somejs.js"></script>

<style>
.green{
 background-color:green;
}
</style>
</head>
<body>
  <table>
    <tbody data-bind="foreach:ajaxData">
      <tr data-bind="css{'green:viewed'}">
       <td data-bind="text:name"></td><td data-bind="text:surname"></td>
      </tr>
    </tbody>
  </table>
</boby>
</html>

........
格林先生{
背景颜色:绿色;
}
问题是,当我进行调用时,我必须重新填充数组ajaxData,当我这样做时,会出现某种“闪烁”,我想要的是找到任何更改的项并仅显示它们

有三种不同的情况:

  • 中存在Id,但名称和姓氏不同,然后我想更改名称和姓氏
  • Javascript中存在的项在调用返回的数据中不存在,因此我希望从ajaxData中删除
  • 返回的数据中不存在项,因此我希望添加到ajaxData可观察数组的末尾
  • 你们知道怎么做吗


    注意:问题是如何进行比较。我如何知道已经返回的数据中是否存在一个返回值。

    您的三个要求正是将为您提供的

    但在此之前,在您的一般方法中有几件事情需要解决

    首先,让我们从viewmodel中获取Ajax内容。一个在一个地方收集所有API调用并将它们作为函数公开的对象怎么样

    这将公开
    .getData()
    (它反过来在内部使用
    .get()


    接下来,不要将viewmodels称为“Viewmodel”。这是他们的目的,不应该是他们的名字。这里似乎有两种类型的东西,项目和项目列表。我不知道你的物品实际上是什么,所以我坚持使用
    Item
    ,你可以选择一个更好的。让我们做两个构造函数:

    function Item(data) {
      var self = this;
      self.id = parseInt(data.id);
      self.name = ko.observable(data.name);
      self.surname = ko.observable(data.surname);
      self.viewed = ko.observable(true);
      setTimeout(function () {
        self.viewed(false);
      }, 600);
    }
    
    function ItemList() {
      var self = this;
      self.data = ko.observableArray();
    
      self.init = function (data) {
        ko.mapping.fromJS(data, ItemList.mapping, self);
      };
      self.load = function () {
        API.getData().done(self.init);
      };
    }
    
    注意如何调用
    API
    ,这使得
    ItemList
    viewmodel更易于阅读。还要注意如何将
    load
    init
    分开,使您能够使用未通过Ajax获得的数据初始化viewmodel(可能是localStorage?)

    您可以在这里看到我们如何调用
    ko.mapping.fromJS
    。为了将传入对象映射到功能正常的viewmodel,应像调用数据属性一样调用viewmodel属性

    假设您的Ajax响应如下所示:

    {
      status: "ok",
      data: [
        {id: 1, name: "Doctor", surname: "Evil"},
        {id: 2, name: "Austin", surname: "Powers"}
      ]
    }
    
    有两个属性,
    状态
    数据

    • status
      我们想忽略它,它对于viewmodel的功能并不重要
    • 数据
      包含一个对象列表,这些对象应成为同名可观察数组中的
      实例
    为此,映射插件需要说明。为了方便起见,我们可以将它们放到
    ItemList
    对象上

    ItemList.mapping = {
      ignore: ["status"],
      data: {
        key: function (data) {
          return ko.unwrap(data.id);
        },
        create: function (options) {
          return new Item(options.data);
        }
      }
    };
    
    这告诉映射插件不要麻烦处理
    状态
    ,而要处理
    数据中的对象

    • 函数将用于确定对象的ID,因此映射插件知道何时应使用传入对象更新现有viewmodel。为此,我们使用
      id
      属性
    • create
      功能将用于将传入的普通对象转换为
      Item
      实例
    现在,每次对来自服务器的新数据调用
    ko.mapping.fromJS
    ,knockout都会挑选现有对象,只更新已更改的属性,而不是重新绘制整个列表。缺少的对象将从屏幕上删除,新对象将添加


    视图保持不变:

    <table>
        <tbody data-bind="foreach: data">
            <tr data-bind="css: {green: viewed}">
                <td data-bind="text: name"></td>
                <td data-bind="text: surname"></td>
            </tr>
        </tbody>
    </table>
    
    .green{
    背景颜色:绿色;
    }
    
    

    在Ajax调用之前存储
    AjaxItem
    对象列表。比较响应数据,然后相应地添加、删除或更新。问题是如何进行比较。看看这个提琴是否有用:(我没有测试它,您可能需要调整它)问题是,当发生错误时,响应可能返回错误状态。抛出“err”时,我不返回数据,或者返回的数据可能包含字符串而不是对象数组。我将如何处理?这取决于你想如何处理。你试过我的剧本在那种情况下的作用吗?我在代码中使用的Ajax模型应该很容易修改。
    <table>
        <tbody data-bind="foreach: data">
            <tr data-bind="css: {green: viewed}">
                <td data-bind="text: name"></td>
                <td data-bind="text: surname"></td>
            </tr>
        </tbody>
    </table>