2016-04-04 13 views
8

Tôi bắt đầu bằng một ứng dụng TODO đơn giản với Aurelia, RethinkDB & Socket.IO. Tôi dường như có vấn đề với tái rendering hoặc đánh giá lại một đối tượng được thay đổi thông qua Socket.IO. Vì vậy, về cơ bản, mọi thứ hoạt động tốt trên trình duyệt đầu tiên nhưng không được hiển thị lại trong trình duyệt thứ hai trong khi hiển thị đối tượng trong giao diện điều khiển hiển thị sự khác biệt trong đối tượng của tôi. Vấn đề là chỉ cập nhật một đối tượng, nó hoạt động hoàn hảo trên việc tạo/xóa đối tượng từ mảng các mục cần làm.Cách buộc ràng buộc đánh giá lại hoặc tái dựng hình trong Aurelia

HTML

<ul> 
    <li repeat.for="item of items"> 
     <div show.bind="!item.isEditing"> 
     <input type="checkbox" checked.two-way="item.completed" click.delegate="toggleComplete(item)" /> 
     <label class="${item.completed ? 'done': ''} ${item.archived ? 'archived' : ''}" click.delegate="$parent.editBegin(item)"> 
      ${item.title} 
     </label> 
     <a href="#" click.delegate="$parent.deleteItem(item, $event)"><i class="glyphicon glyphicon-trash"></i></a> 
     </div> 
     <div show.bind="item.isEditing"> 
     <form submit.delegate="$parent.editEnd(item)"> 
      <input type="text" value.bind="item.title" blur.delegate="$parent.editEnd(item)" /> 
     </form> 
     </div> 
    </li> 
    </ul> 

NodeJS với RethinkDB changefeeds

// attach a RethinkDB changefeeds to watch any changes 
r.table(config.table) 
    .changes() 
    .run() 
    .then(function(cursor) { 
     //cursor.each(console.log); 
     cursor.each(function(err, item) { 
     if (!!item && !!item.new_val && item.old_val == null) { 
      io.sockets.emit("todo_create", item.new_val); 
     }else if (!!item && !!item.new_val && !!item.old_val) { 
      io.sockets.emit("todo_update", item.new_val); 
     }else if(!!item && item.new_val == null && !!item.old_val) { 
      io.sockets.emit("todo_delete", item.old_val); 
     } 
     }); 
    }) 
    .error(function(err){ 
     console.log("Changefeeds Failure: ", err); 
    }); 

đang Aurelia xem Socket.on

// update item 
socket.on("todo_update", data => { 
    let pos = arrayFindObjectIndex(this.items, 'id', data.id); 
    if(pos >= 0) { 
    console.log('before update'); 
    console.log(this.items[pos]); 
    this.items[pos] = data; 
    this.items[pos].title = this.items[pos].title + ' [updated]'; 
    console.log('after update'); 
    console.log(this.items[pos]); 
    } 
}); 

// create item, only add the item if we don't have it already in the items list to avoid dupes 
socket.on("todo_create", data => { 
    if (!_.some(this.items, function (p) { 
    return p.id === data.id; 
    })) { 
    this.items.unshift(data); 
    } 
}); 

// delete item, only delete item if found in items list 
socket.on("todo_delete", data => { 
    let pos = arrayFindObjectIndex(this.items, 'id', data.id); 
    if(pos >= 0) { 
    this.items.splice(pos, 1); 
    } 
}); 

Các socket.on("todo_update", ...){} không được làm cho trình duyệt thứ hai lại làm nhưng thấy đối tượng trong giao diện điều khiển trước/sau khi cập nhật hiển thị sự khác biệt trong chính đối tượng. Tôi thậm chí đã thay đổi thuộc tính tiêu đề cần làm và điều đó cũng không được hiển thị lại.

Làm cách nào để Aurelia hiển thị lại trong trình duyệt thứ hai của tôi với các thuộc tính đối tượng mới? Đừng quá khó khăn với tôi, tôi đang học Aurelia/RethinkDB/NodeJS/Socket.IO cùng một lúc ...

Trả lời

16

Aurelia quan sát những thay đổi đối với nội dung của một mảng bằng cách ghi đè các phương thức đột biến của mảng (push , pop, splice, shift, vv). Điều này làm việc tốt cho hầu hết các trường hợp sử dụng và thực hiện thực sự tốt (không có kiểm tra bẩn, cực kỳ nhẹ về mặt bộ nhớ và CPU). Thật không may, điều này lá một cách đột biến một mảng mà aurelia không thể "nhìn thấy": chuyển nhượng chỉ mục ... ví dụ myArray[6] = 'foo'. Vì không có phương thức mảng nào được gọi, hệ thống liên kết không biết mảng đã thay đổi.

Trong trường hợp của bạn, hãy thử thay đổi này:

// update item 
socket.on("todo_update", data => { 
    let pos = arrayFindObjectIndex(this.items, 'id', data.id); 
    if(pos >= 0) { 
    console.log('before update'); 
    console.log(this.items[pos]); 

    this.items[pos] = data; // <-- change this to: this.items.splice(pos, 1, data); 

    this.items[pos].title = this.items[pos].title + ' [updated]'; 
    console.log('after update'); 
    console.log(this.items[pos]); 
    } 
}); 
+4

Fantastic, giải thích được chính xác những gì tôi muốn biết và vẫn ra theo kiểm tra bẩn ... là tài liệu mà ở đâu đó bởi bất kỳ thay đổi? Thông tin này là vàng :) – ghiscoding

Các vấn đề liên quan