2014-04-21 20 views
6

Tôi muốn tạo đối tượng javascript từ mẫu. Vấn đề là tôi không biết mẫu sẽ trông như thế nào trước đây. Như một ví dụ đơn giản, nếu tôi đã có mẫu chức năngTạo đối tượng Javascript từ mẫu

template = function (data) { 
    return { 
     title: data.title 
    } 
} 

sau đó tôi có thể chạy template({ title: "Steve" }) và lấy lại đối tượng

{ title: "Steve" } 

data.title không được đánh giá cho đến khi tôi gọi là mẫu chức năng. Nhưng tôi đang xây dựng một đối tượng dựa trên đầu vào của người dùng, nơi các tên trường không được biết trước và có thể được lồng sâu ở bất cứ đâu trong đối tượng.

Nếu tôi xác định đối tượng được trả về trước thì trường data.title trong ví dụ này đã được đánh giá và sẽ không sử dụng dữ liệu đầu vào. Ví dụ, tôi muốn để có thể xác định các mẫu đối tượng như

obj = { title: this.title } 

sau đó xác định lại mẫu như

template = function() { 
    return obj 
} 

và gọi template.call({title:"Steve"}). Nhưng hiện nay tôi nhận được lại

{ title: undefined } 

this.title đã được đánh giá khi tôi định nghĩa obj. Có lẽ tôi đang tiếp cận điều này sai, bởi vì tôi tiếp tục đi đến kết luận rằng tôi phải sửa đổi hàm bằng cách xâu chuỗi nó, sửa đổi chuỗi để bao gồm mã chưa được đánh giá this.title và tạo một hàm mới từ chuỗi. Nhưng điều đó có vẻ giống như một ý tưởng khủng khiếp đơn giản.

Và vượt qua đối tượng tìm kiếm các giá trị đặc biệt để thay thế có vẻ tốn kém và phức tạp. Tôi cũng tìm một số loại thư viện JavaScript đối tượng khuôn mẫu nhưng không tìm thấy bất cứ điều gì.

EDIT: Để làm cho nó rõ ràng hơn rằng các dữ liệu đầu vào và các cấu trúc mẫu sẽ không nhất thiết phải phù hợp với, tôi có thể muốn có một mẫu mà trông giống như

template = function (data) { 
    return { 
     name: "Alfred", 
     stats: { 
      age: 32, 
      position: { 
       level: 10, 
       title: data.title 
      } 
     } 
    } 
} 

và gọi template({title:"Manager"}) để có được

{ "tên": "Alfred", "số liệu thống kê": { "tuổi": 32, "vị trí": { "cấp độ": 10, "title": "Người quản lý" } } }

+0

http://api.jquery.com/jquery.extend/ – setec

+0

Cảm ơn nhưng có lẽ tôi nên rõ ràng hơn: vấn đề với điều này là t dữ liệu đầu vào của anh ta sẽ không khớp với cấu trúc của mẫu. Các giá trị đầu vào có thể phải được đặt trong một phần lồng nhau sâu sắc của đối tượng hoặc nhiều lần trong cùng một đối tượng. Tôi sẽ không "biết" nó trông như thế nào khi tôi gọi hàm mẫu. –

Trả lời

5

Vì vậy, tôi đã giải quyết điều này bằng cách (ab) sử dụng các hàm làm siêu dữ liệu để đánh dấu các giá trị sẽ được thay thế trong mẫu. Điều này có thể được thực hiện bởi hai điều:

  1. Tôi chỉ cần giá trị JSON hợp lệ, vì vậy tôi có thể yên tâm nói rằng chức năng không phải là người sử dụng đầu vào nghĩa đen
  2. JSON.stringify có replacer parameter mà sẽ đi qua các vật thể và có thể được sử dụng để truyền các dữ liệu đầu vào cho các mẫu

sử dụng một máy phát điện mẫu như thế này

var templateMaker = function (object) { 
    return function (context) { 
     var replacer = function (key, val) { 
      if (typeof val === 'function') { 
       return context[val()] 
      } 
      return val; 
     } 
     return JSON.parse(JSON.stringify(obj, replacer)) 
    } 
} 

tôi tạo ra một đối tượng mẫu, thay thế f tên ield với chức năng mà trả lại tên trường

var obj = { 
    name: "Alfred", 
    stats: { 
     age: 32, 
     position: { 
      title: function() { return 'title' }, 
      level: function() { return 'level' } 
     } 
    } 
} 

sau đó tôi có thể tạo mẫu chức năng, xác định đầu vào của tôi, và làm cho nó đến một đối tượng

var template = templateMaker(obj); 

var data = { 
    title: "Manager", 
    level: 10 
} 

var rendered = template(data); 

và kỳ diệu, sản lượng đối tượng trông giống như

{ "name": "Alfred", "stats": { "age": 32, "position": { "title": "Manager", "level": 10 } } }

3

Có thể công cụ tạo mẫu như Mustache sẽ giúp bạn với điều này.

Bạn có thể xác định mẫu đối tượng của bạn trong chuỗi:

var template = '{ title: {{title}} }';

sau đó làm cho nó với các dữ liệu, và chuyển nó sang json:

var data = {title: 'I am title'}; 
var obj = JSON.parse(Mustache.render(template, data)); 

CẬP NHẬT:

Tôi đã đọc ví dụ được cập nhật của bạn, đây là ví dụ tương ứng:

var template = JSON.stringify({ 
    name: "Alfred", 
    stats: { 
     age: 32, 
     position: { 
      level: 10, 
      title: '{{title}}' 
     } 
    } 
}); 

var data = {title: 'I am title'}; 
var obj = JSON.parse(Mustache.render(template, data)); 

obj.stats.position.title == "I am title"; 
+0

Cảm ơn. Tôi đã xem xét một cái gì đó như thế này nhưng vì người dùng sẽ chỉ định các giá trị khác trong đối tượng, tôi không chắc chắn làm thế nào để phân biệt mẫu của tôi '{{var}}' từ đầu vào của người dùng mà họ muốn chuỗi "{{var} } ". Có lẽ một cách tầm thường để làm điều này tôi đang thiếu? –

+0

Tôi chưa nghĩ ra cách để giải quyết điều đó. – wong2

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