2015-05-08 30 views
24

Tuyên bố từ chối trách nhiệm: Đây là nỗ lực đầu tiên của tôi khi xây dựng ứng dụng MVVM mà trước đây tôi chưa từng làm việc với vue.js, vì vậy vấn đề của tôi là vấn đề cơ bản hơn .Vue JS Xem đối tượng lồng nhau sâu


Theo quan điểm của tôi, tôi có hai loại khối với hộp kiểm sau:

  • Loại 1: block/hộp kiểm
  • Loại 2: khối/tiêu đề/hộp kiểm

Các cơ bản đối tượng có cấu trúc như sau:

{ 
    "someTopLevelSetting": "someValue", 
    "blocks": [ 
    { 
     "name": "someBlockName", 
     "categryLevel": "false", 
     "variables": [ 
     { 
      "name": "someVarName", 
      "value": "someVarValue", 
      "selected": false, 
      "disabled": false 
     } 
     ] 
    }, 
    { 
     "name": "someOtherBlockName", 
     "categryLevel": "true", 
     "variables": [ 
     { 
      "name": "someVarName", 
      "value": "someVarValue", 
      "categories": [ 
      { 
       "name": "SomeCatName", 
       "value": "someCatValue", 
       "selected": false, 
       "disabled": false 
      } 
      ] 
     } 
     ] 
    } 
    ] 
} 

mục tiêu của tôi

hộp kiểm Lựa chọn:

  1. Người dùng nhấp vào hộp kiểm, hộp kiểm được chọn (selected = true)
  2. Một phương pháp là bắn để kiểm tra nếu có hộp kiểm khác cần phải được bị vô hiệu hóa (disabled = true). (Nếu phương pháp này đã thực sự bị vô hiệu hóa bất cứ điều gì, nó cũng đòi hỏi bản thân một lần nữa, bởi vì các mặt hàng khác có thể lần lượt phụ thuộc vào mục vô hiệu hóa)
  3. Phương pháp khác cập nhật một số thứ khác, như biểu tượng vv

hộp kiểm Xoá

Người dùng có thể nhấp vào nút "xóa", bỏ chọn tất cả các hộp kiểm trong danh sách (được chọn = false). Hành động này cũng nên kích hoạt các phương pháp mà tùy chọn vô hiệu hóa hộp kiểm và cập nhật biểu tượng vv

phương pháp hiện tại của tôi(mà dường như không hoàn toàn đúng)

  • Thuộc tính lựa chọn của đĩa dữ liệu mô hình được gắn với trạng thái kiểm tra của phần tử hộp kiểm qua chỉ thị v-model.
  • Thuộc tính bị vô hiệu hóa (từ mô hình) bị ràng buộc với thuộc tính của lớp và thuộc tính bị tắt. Trạng thái này được thiết lập theo phương pháp đã nói ở trên.
  • Để khởi tạo các phương pháp vô hiệu hóa các hộp kiểm và thay đổi một số biểu tượng, tôi đang sử dụng chỉ thị v-on="change: checkboxChange(this)". Tôi nghĩ rằng tôi cần phải làm phần này khác nhau phương pháp
  • Các clearList được gọi qua v-on="click: clearList(this)"

Những vấn đề với thiết lập hiện tại của tôi là sự kiện thay đổi không được bắn khi các hộp kiểm sẽ bị xóa programatically (tức không phải do tương tác của người dùng).

Những gì tôi muốn thay
Đối với tôi điều hợp lý nhất để làm là nên sử dụng this.$watch và theo dõi những thay đổi trong mô hình, thay vì lắng nghe cho các sự kiện DOM.

Khi có thay đổi, sau đó tôi sẽ cần phải xác định mục chính xác nào đã thay đổi và thực hiện hành động đó. Tôi đã cố tạo hàm $watch quan sát mảng blocks. Điều này dường như nhận các thay đổi tốt, nhưng nó trả về đối tượng đầy đủ, trái ngược với thuộc tính cá nhân đã thay đổi. Ngoài ra đối tượng này thiếu một số thuộc tính trợ giúp thuận tiện, như $parent.

Tôi có thể nghĩ ra một số cách để làm cho ứng dụng hoạt động (như kích hoạt sự kiện thay đổi theo cách thủ công trong phương thức clearList của tôi, v.v.) xử lý này.

Trả lời

7

Vì không ai trả lời và tôi đã giải quyết/giải quyết vấn đề này ngay bây giờ, tôi nghĩ việc di chuyển sẽ hữu ích khi đăng giải pháp của tôi. Xin lưu ý rằng tôi không chắc chắn giải pháp của tôi là làm thế nào các loại điều cần được giải quyết, nó hoạt động mặc dù.

Thay vì sử dụng trình xử lý sự kiện này v-on="change: checkboxChange(this)" Tôi hiện đang sử dụng chỉ thị tùy chỉnh nghe cả thuộc tính mô hình đã chọn và đã tắt, như sau: v-on-filter-change="selected, disabled".

Chỉ thị trông như thế này:

directives: { 
    'on-filter-change': function(newVal, oldVal) { 
     // When the input elements are first rendered, the on-filter-change directive is called as well, 
     // but I only want stuff to happen when a user does someting, so I return when there is no valid old value 
     if (typeof oldVal === 'undefined') { 
      return false; 
     } 
     // Do stuff here 
     // this.vm is a handy attribute that contains some vue instance information as well as the current object 
     // this.expression is another useful attribute with which you can assess which event has taken place 
    } 
}, 

Các mệnh đề if có vẻ hơi hacky, nhưng tôi không thể tìm thấy một cách khác. Ít nhất tất cả đều hoạt động.

Có lẽ điều này sẽ hữu ích cho người nào đó trong tương lai.

55

Bạn có thể sử dụng phương pháp 'watch' .. ví dụ nếu dữ liệu của bạn là:

data: { 
    block: { 
     checkbox: { 
      active:false 
     }, 
     someotherprop: { 
      changeme: 0 
     } 
    } 
} 

Bạn có thể làm một cái gì đó như thế này:

data: {...}, 
watch: { 
    'block.checkbox.active': function() { 
     // checkbox active state has changed 
     this.block.someotherprop.changeme = 5; 
    } 
} 
+1

.selected and .disabled là các thuộc tính của các đối tượng biến ẩn danh thuộc mảng biến. Ví dụ của bạn hoạt động vì nó chỉ là một đối tượng không phải là mảng. – Hendrik

+0

Tôi đã làm một cái gì đó như block.checkbox.active, nhưng nó không hoạt động cho đến khi tôi thêm chúng vào "" như bạn đã đề cập ở trên. Cảm ơn. Nó hoạt dộng bây giờ. –

5

Nếu bạn muốn xem các đối tượng như tổng thể với tất cả các thuộc tính của nó và không chỉ có một thuộc tính, bạn có thể làm điều này thay thế:

data() { 
    return { 
     object: { 
      prop1: "a", 
      prop2: "b", 
     }  
    } 
}, 
watch: { 
    object: { 
     handler(newVal, oldVal) { 
      // do something with the object 
     }, 
     deep: true, 
    }, 
}, 

thông báo handlerdeep: true

+0

Cảm ơn vì điều này. Tuy nhiên, vì câu hỏi của tôi đã hơn hai tuổi, và tôi đã không sử dụng Vue kể từ đó, tôi không thể xác minh liệu điều này có hiệu quả hay không. – Hendrik

+1

@Hendrik đừng lo lắng, tôi hy vọng điều này sẽ giúp một người có cùng vấn đề – peerbolte

+0

Bạn có biết tôi nên làm gì nếu tôi chỉ muốn xem 'prop1'? –

2

Giải pháp khác không được đề cập ở đây: Sử dụng tùy chọn deep.

watch:{ 
    block: { 
    handler: function() {console.log("changed") }, 
    deep: true 
    } 
} 
Các vấn đề liên quan