// Backbone.js 0.9.2 // (c) 2010-2012 Jeremy Ashkenas, DocumentCloud Inc. // 백본은 MIT 라이선스에 따라 자유롭게 배포될 수 있습니다. // 모든 세부 사항 및 문서는 다음을 참조하세요. // http://backbonejs.org (기능() { // 브라우저에서는 창 객체로 표시되고 Node.js에서는 전역 객체로 표시되는 전역 객체를 생성합니다. var 루트 = 이것; // 덮어쓰기 전 "Backbone" 변수의 값을 저장합니다. // 이름 충돌이 있거나 사양을 고려하는 경우 Backbone.noConstrict() 메서드를 사용하여 변수가 Backbone에 의해 점유되기 전의 값을 복원하고 이름 변경을 위해 Backbone 객체를 반환할 수 있습니다. var PreviousBackbone = root.Backbone; //Array.prototype의 슬라이스 및 스플라이스 메소드를 호출을 위한 로컬 변수에 캐시합니다. var 슬라이스 = Array.prototype.slice; var splice = Array.prototype.splice; var 백본; if( 내보내기 유형 !== '정의되지 않음') { 백본 = 수출; } 또 다른 { 백본 = 루트.백본 = {}; } //백본 버전 정의 백본.VERSION = '0.9.2'; // 서버 환경에서 Underscore를 자동으로 가져옵니다. Backbone의 일부 메소드는 Underscore에 의존하거나 상속받습니다. var _ = 루트._; if(!_ && ( typeof 필요 !== '정의되지 않음')) _ = require('밑줄'); // 타사 라이브러리를 보기(View), 이벤트 처리 및 서버 데이터와의 동기화(sync) 중에 라이브러리의 메소드를 호출하는 데 사용되는 통합 변수 "$"로 정의합니다. // 지원되는 라이브러리에는 jQuery, Zepto 등이 있습니다. 구문은 동일하지만 Zepto가 모바일 개발에 더 적합합니다. 주로 Webkit 핵심 브라우저를 대상으로 합니다. // Backbone에서 사용하기 위해 jQuery와 유사한 구문으로 사용자 정의 라이브러리를 사용자 정의할 수도 있습니다(때로는 jQuery 또는 Zepto보다 가벼운 사용자 정의 버전이 필요할 수 있음) // 여기에 정의된 "$"는 지역 변수이므로 Backbone 프레임워크 외부의 타사 라이브러리를 정상적으로 사용하는 데에는 영향을 미치지 않습니다. var $ = root.jQuery || root.Zepto || // 타사 라이브러리를 수동으로 설정 // Backbone을 가져오기 전에 타사 라이브러리를 가져오지 않은 경우 setDomLibrary 메소드를 통해 "$" 지역 변수를 설정할 수 있습니다. // setDomLibrary 메소드는 Backbone에서 사용자 정의 라이브러리를 동적으로 가져오는 데에도 일반적으로 사용됩니다. Backbone.setDomLibrary = 함수(lib) { $ = 라이브러리; }; //"Backbone" 이후 프레임워크 이름 지정을 포기하고 일반적으로 이름 지정 충돌을 피하거나 이름 지정 방법을 표준화하는 데 사용되는 Backbone 개체를 반환합니다. // 예를 들어: // var bk = Backbone.noConstrict(); // "Backbone" 명명을 취소하고 Backbone 객체를 bk 변수에 저장합니다. // console.log(Backbone); // 이 변수는 더 이상 Backbone 객체에 접근할 수 없으며 Backbone이 정의되기 전의 값으로 복원됩니다. // var MyBackbone = bk; // 그리고 bk는 Backbone 객체를 저장하고 이름을 MyBackbone으로 바꿉니다. Backbone.noConstrict = function() { root.Backbone = 이전백본; 이거 돌려줘; }; // REST를 지원하지 않는 브라우저의 경우 Backbone.emulateHTTP = true로 설정할 수 있습니다. // 서버 요청은 POST 모드로 전송되며 작업 이름을 식별하기 위해 _method 매개 변수가 데이터에 추가되고 X-HTTP-Method-Override 헤더 정보도 전송됩니다. Backbone.emulateHTTP = 거짓; // application/json 인코딩을 지원하지 않는 브라우저의 경우 Backbone.emulateJSON = true로 설정할 수 있습니다. //요청 유형을 application/x-www-form-urlencoded로 설정하고 호환성을 위해 모델 매개변수에 데이터를 배치합니다. Backbone.emulateJSON = 거짓; // 사용자 정의 이벤트와 관련된 Backbone.Events // ------------------ // eventSplitter는 여러 이벤트를 처리할 때 이벤트 이름에 대한 구문 분석 규칙을 지정합니다. var eventSplitter = /s /; // 사용자 정의 이벤트 관리자 // 이벤트 관련 메소드를 객체에 바인딩하여 해당 객체에 커스텀 이벤트를 추가, 삭제, 트리거할 수 있습니다. var 이벤트 = Backbone.Events = { // 사용자 정의 이벤트와 콜백 함수를 현재 객체에 바인딩합니다. //콜백 함수의 컨텍스트 개체는 지정된 컨텍스트입니다. 컨텍스트가 설정되지 않은 경우 컨텍스트 개체는 기본적으로 현재 바인딩된 이벤트의 개체로 설정됩니다. // 이 메소드는 DOM Level2의 addEventListener 메소드와 유사합니다. // 이벤트를 사용하면 공백, 탭 등의 공백 문자로 구분된 여러 이벤트 이름을 지정할 수 있습니다. // 이벤트 이름이 "all"인 경우, 트리거 메소드를 호출하여 이벤트가 트리거되면 "all" 이벤트에 바인딩된 모든 콜백 함수가 호출됩니다. on : 함수(이벤트, 콜백, 컨텍스트) { //일부 함수에서 사용되는 지역 변수 정의 var 호출, 이벤트, 노드, 꼬리, 목록; //콜백 함수를 설정해야 합니다. if(!콜백) 이거 돌려줘; // eventSplitter를 통해 이벤트 이름을 구문 분석하고, 분할을 사용하여 여러 이벤트 이름을 배열로 분할합니다. // 일반적으로 여러 이벤트 이름을 지정하려면 공백 문자를 사용합니다. 이벤트 = events.split(eventSplitter); // 호출은 현재 객체에 바인딩된 이벤트 및 콜백 함수 목록을 기록합니다. 호출 = this._callbacks || (this._callbacks = {}); // 이벤트 이름 목록을 반복하고 처음부터 끝까지 이벤트 이름을 이벤트 변수에 저장합니다. while(이벤트 = events.shift()) { // 이벤트에 바인딩된 콜백 함수를 가져옵니다. // 목록은 단일 이벤트 이름에 바인딩된 콜백 함수 목록을 저장합니다. // 함수 목록은 배열로 저장되지 않고, 여러 객체의 다음 속성을 통해 순차적으로 연관됩니다. /**数据格式如: * { * 꼬리: {객체}, * 다음: { * 콜백: {함수}, * 컨텍스트: {객체}, * 다음: { * 콜백: {함수}, * 컨텍스트: {객체}, * 다음: {객체} * } * } * }*/ // 목록의 각 수준에 있는 다음 객체는 콜백 이벤트와 관련된 정보(함수 본문, 컨텍스트 및 다음 콜백 이벤트)를 저장합니다. // 이벤트 목록의 최상위 수준에는 마지막으로 바인딩된 콜백 이벤트의 식별자를 저장하는 tail 개체가 저장됩니다(마지막 콜백 이벤트의 다음 개체와 동일한 개체). // tail 식별자를 통해 콜백 목록을 순회하면 마지막 콜백 함수에 도달했음을 알 수 있습니다. 목록 = 통화[이벤트]; // 노드 변수는 이 콜백 함수와 관련된 정보를 기록하는 데 사용됩니다. //tail은 마지막으로 바인딩된 콜백 함수의 식별자만 저장합니다. // 따라서 콜백 함수가 이전에 바인딩된 경우 이전 tail을 노드에 객체로 할당한 다음 tail에 대한 새 객체 식별자를 생성합니다. // 이전 콜백의 tail 객체에 이 콜백 이벤트를 추가하는 이유는 콜백 함수 목록의 객체 계층 구조를 바인딩 순서대로 정렬하기 위함입니다. (최근 바인딩된 이벤트는 맨 아래에 배치됩니다.) 노드 = 목록 ? 목록.꼬리: {}; node.next = 꼬리 = {}; //이 콜백의 함수 본문과 컨텍스트 정보를 기록합니다. node.context = 컨텍스트; node.callback = 콜백; //현재 이벤트의 콜백 목록을 재조립합니다. 이 콜백 이벤트가 목록에 추가되었습니다. 통화[이벤트] = { 꼬리: 꼬리, 다음 : 목록 ? list.next : 노드 }; } // 메소드 체인 호출을 용이하게 하기 위해 현재 객체를 반환합니다. 이거 돌려줘; }, // 객체에 바인딩된 이벤트나 콜백 함수를 제거합니다. 이벤트, 콜백, 컨텍스트를 통해 삭제해야 하는 이벤트나 콜백 함수를 필터링할 수 있습니다. // - 컨텍스트가 비어 있으면 콜백에 지정된 모든 함수를 제거합니다. // - 콜백이 비어 있으면 이벤트의 모든 콜백 함수를 제거합니다. // - 이벤트가 비어 있으나 콜백이나 컨텍스트가 지정된 경우 콜백이나 컨텍스트에 지정된 콜백 함수를 제거합니다. (이벤트 이름은 구분되지 않습니다.) // - 매개변수가 전달되지 않으면 객체에 바인딩된 모든 이벤트와 콜백 함수를 제거합니다. off : 함수(이벤트, 콜백, 컨텍스트) { var 이벤트, 호출, 노드, 테일, cb, ctx; // 이벤트가 없거나 *모든* 이벤트를 제거합니다. //현재 객체에는 바인딩된 이벤트가 없습니다. if(!( 통화 = this._callbacks)) 반품; // 매개변수가 지정되지 않은 경우 모든 이벤트 및 콜백 함수를 제거합니다(_callbacks 속성 제거). if(!(이벤트 || 콜백 || 컨텍스트)) { this._callbacks 삭제; 이거 돌려줘; } // 제거해야 할 이벤트 목록을 구문 분석합니다. // - 이벤트가 지정되면 eventSplitter에 따라 이벤트 이름이 구문 분석됩니다. // - 이벤트가 지정되지 않은 경우 바인딩된 모든 이벤트의 이름 목록을 구문 분석합니다. 이벤트 = 이벤트 ? events.split(eventSplitter) : _.keys(calls); // 루프 이벤트 이름 목록 while(이벤트 = events.shift()) { // 목록에서 현재 이벤트 객체를 제거하고 노드 변수에 캐시합니다. 노드 = 호출[이벤트]; 통화 삭제[이벤트]; // 현재 이벤트 객체가 존재하지 않는 경우(또는 제거 필터 조건이 지정되지 않은 경우 현재 이벤트 및 모든 콜백 함수가 제거되는 것으로 간주) 이 작업을 종료합니다(이전 단계에서 이벤트 객체가 제거되었습니다) ) if(!노드 || !(콜백 || 컨텍스트)) 계속하다; // 표시된 콜백을 생략하고 새 목록을 만듭니다. // 콜백 함수나 컨텍스트 필터 조건에 따라 새로운 이벤트 객체를 조립하고 리바인드합니다. 꼬리 = node.tail; // 이벤트의 모든 콜백 객체를 순회합니다. while(( node = node.next) !== tail) { cb = node.callback; ctx = node.context; // 콜백 함수와 파라미터에 있는 context를 기반으로 콜백 함수를 필터링하고, 필터링 조건에 맞지 않는 콜백 함수를 이벤트에 다시 바인딩합니다. (위에서 이벤트의 콜백 함수를 모두 제거했기 때문입니다.) if((콜백 && cb !== 콜백) || (컨텍스트 && ctx !== 컨텍스트)) { this.on(이벤트, cb, ctx); } } } 이거 돌려줘; }, // 정의된 하나 이상의 이벤트를 트리거하고 바인딩된 콜백 함수 목록을 순서대로 실행합니다. 트리거 : 함수(이벤트) { var 이벤트, 노드, 호출, 꼬리, 인수, 모두, 나머지; //현재 객체에는 바인딩된 이벤트가 없습니다. if(!( 통화 = this._callbacks)) 이거 돌려줘; // 콜백 함수 목록에 바인딩된 "모든" 이벤트 목록을 가져옵니다. 모두 = 통화.모두; // eventSplitter 규칙에 따라 배열로 트리거되어야 하는 이벤트 이름을 구문 분석합니다. 이벤트 = events.split(eventSplitter); // 두 번째부터 트리거의 매개변수를 나머지 변수에 기록하고, 이는 차례로 콜백 함수에 전달됩니다. 나머지 = Slice.call(인수, 1); // 트리거되어야 하는 이벤트 목록을 반복합니다. while(이벤트 = events.shift()) { // 여기의 노드 변수는 현재 이벤트의 모든 콜백 함수 목록을 기록합니다. if( 노드 = 호출[이벤트]) { //tail 변수는 마지막 바인딩 이벤트의 개체 ID를 기록합니다. 꼬리 = node.tail; //노드 변수의 값은 이벤트 바인딩 순서에 따라 바인딩된 단일 콜백 이벤트 객체에 순차적으로 할당됩니다. // 마지막으로 바인딩된 이벤트의 next 속성은 tail과 동일한 객체를 참조하며, 이는 목록의 끝에 도달했는지 판단하는 기준으로 사용됩니다. while(( node = node.next) !== tail) { // 바인딩된 모든 이벤트를 실행하고 트리거 호출 시 매개변수를 콜백 함수에 전달합니다. node.callback.apply(node.context || this, 나머지); } } // all 변수는 바인딩 중 'all' 이벤트를 기록합니다. 즉, 어떤 이벤트가 호출되면 'all' 이벤트에 포함된 콜백 함수가 실행됩니다. // - "all" 이벤트의 콜백 함수는 바인딩 순서와 관계없이 현재 이벤트의 모든 콜백 함수 목록이 실행된 후 순차적으로 실행됩니다. // - "all" 이벤트는 일반 이벤트가 발생할 때 자동으로 호출되어야 합니다. "all" 이벤트가 강제로 트리거되면 해당 이벤트의 콜백 함수가 두 번 실행됩니다. if(노드 = 모두) { 꼬리 = node.tail; //일반 이벤트의 콜백 함수 호출과 다른 점은 all 이벤트는 현재 호출된 이벤트 이름을 콜백 함수의 첫 번째 매개변수로 전달한다는 점입니다. args = [이벤트].concat(rest); // "all" 이벤트의 콜백 함수 목록을 탐색하고 실행합니다. while(( node = node.next) !== tail) { node.callback.apply(node.context || this, args); } } } 이거 돌려줘; } }; // 이전 버전의 Backbone과의 호환성을 위한 바인딩 이벤트 및 릴리스 이벤트에 대한 별칭 Events.bind = 이벤트.온; Events.unbind = Events.off; // Backbone.Model 데이터 객체 모델 //------------- // Model은 Backbone의 모든 데이터 객체 모델의 기본 클래스로, 데이터 모델을 생성하는 데 사용됩니다. // @param {Object} 속성은 모델 생성 시 초기화 데이터를 지정합니다. // @param {Object} 옵션 /*** @format 옵션 * { * 구문 분석: {부울}, * 컬렉션: {컬렉션} * }*/ var Model = Backbone.Model = function(속성, 옵션) { // defaults 변수는 모델의 기본 데이터를 저장하는 데 사용됩니다. var 기본값; // 속성 매개변수가 지정되지 않은 경우 속성을 빈 객체로 설정합니다. 속성 || (속성 = {}); //속성 기본 데이터의 구문 분석 방법을 설정합니다. 예를 들어 기본 데이터는 서버에서 가져옵니다(또는 원본 데이터는 XML 형식임). 설정된 메서드에 필요한 데이터 형식과 호환되도록 구문 분석합니다. 메소드를 사용하여 구문 분석할 수 있습니다. if(옵션 && options.parse) 속성 = this.parse(속성); if( defaults = getValue(this, 'defaults')) { // 모델이 정의될 때 기본값 데이터를 설정하면 초기화 데이터는 기본값 및 속성 매개변수와 병합된 데이터를 사용합니다. (속성의 데이터는 기본값의 동일한 이름으로 데이터를 덮어씁니다.) 속성 = _.extend({}, 기본값, 속성); } // 모델이 속한 Collection 객체를 명시적으로 지정합니다. (모델을 컬렉션에 추가하기 위해 Collection의 add, push 등의 메소드를 호출하면 모델이 속한 Collection 객체가 자동으로 설정됩니다.) if(옵션 && options.collection) this.collection = 옵션.collection; //attributes 속성은 현재 모델의 JSON 객체화된 데이터를 저장하며 모델 생성 시 기본적으로 비어 있습니다. this.attributes = {}; // 이스케이프 메소드를 통해 처리된 데이터를 캐시할 _escapedAttributes 캐시 객체를 정의합니다. this._escapedAttributes = {}; // 각 모델에 대한 고유 식별자를 구성합니다. this.cid = _.uniqueId('c'); //데이터 상태를 기록하는 데 사용되는 일련의 객체를 정의합니다. 구체적인 의미는 객체 정의 시 주석을 참조하세요. this.changed = {}; this._silent = {}; this._pending = {}; // 인스턴스 생성 시 초기화 데이터를 설정합니다. 자동 매개변수를 처음 사용하면 변경 이벤트가 발생하지 않습니다. this.set(속성, { 침묵 : 사실 }); // 초기화 데이터가 위에서 설정되었습니다. 변경된 상태, _silent, _pending 개체가 여기에서 다시 초기화되었을 수 있습니다. this.changed = {}; this._silent = {}; this._pending = {}; // _previousAttributes 변수는 모델 데이터의 복사본을 저장합니다. //change 이벤트에서 모델 데이터가 변경되기 전의 상태를 가져오는 데 사용됩니다. 이전 상태의 데이터는 이전 또는 이전 속성 메소드를 통해 가져올 수 있습니다. this._previousAttributes = _.clone(this.attributes); //초기화 메소드 호출 this.initialize.apply(this, 인수); }; // 모델 프로토타입에 대한 일련의 속성과 메서드를 정의하려면 확장 메서드를 사용하세요. _.extend(Model.prototype, 이벤트, { //변경된 속성은 set 메소드가 호출될 때마다 변경된 데이터의 키 컬렉션을 기록합니다. 변경됨: null, // // 자동 속성이 지정되면 변경 이벤트가 발생하지 않으며, 다음 변경 이벤트가 발생할 때까지 변경된 데이터가 기록됩니다. // _silent 속성은 자동 사용 시 변경된 데이터를 기록하는 데 사용됩니다. _silent : null, _보류 중 : null, // 각 모델의 고유 식별 속성(기본값은 "id", id 속성 이름은 idAttribute를 수정하여 사용자 정의 가능) // 데이터 설정 시 id 속성이 포함된 경우 해당 id가 모델의 id보다 우선 적용됩니다. // ID는 컬렉션에서 모델을 찾고 식별하는 데 사용됩니다. 백엔드 인터페이스와 통신할 때 ID는 레코드의 식별자로도 사용됩니다. id속성: 'id', // 모델 초기화 메소드, 모델 구축 후 자동 호출 초기화 : 함수() { }, // 현재 모델의 데이터 복사본을 반환합니다(JSON 개체 형식). toJSON : 함수(옵션) { return _.clone(this.attributes); }, //attr 속성 이름에 따라 모델의 데이터 값을 가져옵니다. get : 함수(속성) { return this.attributes[attr]; }, //attr 속성 이름에 따라 모델의 데이터 값을 얻습니다. 데이터 값에 포함된 HTML 특수 문자는 & < > // _.escape 메소드를 통해 구현됨 탈출 : 함수(속성) { varhtml; // _escapedAttributes 캐시 객체에서 데이터를 찾고, 데이터가 캐시된 경우 직접 반환합니다. if(html = this._escapedAttributes[attr]) HTML을 반환; // _escapedAttributes 캐시 객체에서 데이터를 찾을 수 없습니다. // 그런 다음 먼저 모델에서 데이터를 가져옵니다. var val = this.get(attr); // _.escape 메서드를 사용하여 데이터의 HTML을 엔터티로 변환하고 다음에 쉽게 검색할 수 있도록 _escapedAttributes 개체에 캐시합니다. return this._escapedAttributes[attr] = _.escape(val == null ? '' : '' val); }, // 모델에 특정 속성이 존재하는지 확인합니다. 해당 속성의 값을 Boolean 유형으로 변환하여 값이 false인 경우 존재하지 않는 것으로 간주합니다. // 값이 false, null, 정의되지 않음, 0, NaN 또는 빈 문자열인 경우 false로 변환됩니다. 있음 : 함수(속성) { return this.get(attr) != null; }, //모델에 데이터를 설정합니다. 키 값이 없으면 새 속성으로 모델에 추가됩니다. 키 값이 이미 있으면 새 값으로 수정됩니다. 설정 : 함수(키, 값, 옵션) { // attrs 변수에 설정해야 하는 데이터 객체를 기록합니다. var 속성, 속성, 발; // 매개변수 형식은 키-값 개체 형식을 허용하거나 키 및 값 매개변수를 통해 별도의 설정을 허용합니다. // key가 객체인 경우 객체 형태로 설정된 것으로 간주하고, 두 번째 매개변수는 옵션 매개변수로 간주한다. if(_.isObject(key) || 키 == null) { 속성 = 키; 옵션 = 가치; } 또 다른 { // 키와 값의 두 매개변수를 별도로 설정하고 데이터를 attrs 객체에 넣어 통합 처리합니다. 속성 = {}; attrs[키] = 값; } // 옵션 구성 항목은 객체여야 합니다. 옵션이 설정되지 않은 경우 기본값은 빈 객체입니다. 옵션 || (옵션 = {}); // 매개변수가 설정되지 않은 경우 아무 작업도 수행되지 않습니다. if(!attrs) 이거 돌려줘; // 설정되는 데이터 객체가 Model 클래스의 인스턴스에 속하는 경우 Model 객체의 데이터 객체 속성을 attrs에 할당합니다. // 일반적으로 이 작업은 한 Model 개체에서 다른 Model 개체로 데이터를 복사할 때 수행됩니다. if(모델 인스턴스 속성) attrs = attrs.attributes; // 옵션 구성 객체에 unset 속성이 설정된 경우 attrs 데이터 객체의 모든 속성을 정의되지 않음으로 재설정합니다. // 일반적으로 한 Model 객체에서 다른 Model 객체로 데이터를 복사할 때 이 작업을 수행하는데, 값은 복사하지 않고 Model 내부의 데이터만 복사하면 됩니다. if(options.unset) for(속성 속의 속성) 속성[속성] = 무효 0; //현재 데이터를 검증하고, 검증에 실패하면 실행을 중지합니다. if(!this._validate(속성, 옵션)) 거짓을 반환; // 설정된 id 속성 이름이 데이터 컬렉션에 포함된 경우 해당 id를 모델의 id 속성에 덮어씁니다. // id 속성명을 커스터마이징한 후 모델의 id 속성에 접근할 때 해당 id에 올바르게 접근할 수 있도록 하기 위한 것입니다. if(attrs의 this.idAttribute) this.id = attrs[this.idAttribute]; var 변경 = options.changes = {}; // 이제 현재 모델의 데이터 객체를 기록합니다. var now = this.attributes; // escaped는 현재 모델에서 escape로 캐시된 데이터를 기록합니다. var escaped = this._escapedAttributes; // prev는 모델의 데이터가 변경되기 전의 값을 기록합니다. var prev = this._previousAttributes || // 설정해야 하는 데이터 객체를 탐색합니다. for(attr in attrs) { // attr은 현재 속성 이름을 저장하고, val은 현재 속성 값을 저장합니다. 값 = 속성[속성]; // 현재 데이터가 모델에 없거나, 변경되었거나, 옵션에 unset 속성 삭제가 지정된 경우 _escapedAttributes의 데이터로 대체된 데이터를 삭제합니다. if(!_.isEqual(now[attr], val) || (options.unset && _.has(now, attr))) { // 이스케이프를 통해 캐시된 데이터만 삭제합니다. 이는 캐시에 있는 데이터가 모델의 실제 데이터와 동기화되도록 하기 위한 것입니다. 삭제 이스케이프됨[attr]; // 자동 속성이 지정되면 이 set 메소드 호출에 의해 변경 이벤트가 발생하지 않으므로 변경된 데이터가 _silent 속성에 기록되므로 다음에 변경 이벤트가 발생할 때 이벤트 청취 기능이 수행됩니다. 데이터가 변경되었음을 알립니다. // 자동 속성이 지정되지 않은 경우 변경 속성의 현재 데이터를 변경된 상태로 직접 설정합니다. (options.silent ? this._silent : 변경)[attr] = true; } // 옵션에 unset이 설정되어 있으면 모델에서 데이터(키 포함)를 삭제합니다. // unset 속성을 지정하지 않으면 신규 또는 수정된 데이터가 추가되는 것으로 간주하여 모델의 데이터 객체에 새로운 데이터가 추가됩니다. 옵션.설정 해제? 지금 삭제[attr] : 지금[attr] = val; // 모델의 데이터가 새 데이터와 일치하지 않으면 데이터가 변경되었음을 의미합니다. if(!_.isEqual(prev[attr], val) || (_.has(now, attr) != _.has(prev, attr))) { // 변경된 속성에 현재 속성의 변경된 상태를 기록합니다. this.changed[attr] = 발; if(!options.silent) this._pending[attr] = true; } 또 다른 { // 데이터가 변경되지 않은 경우 변경된 속성에서 변경된 상태를 제거합니다. 이것을 삭제하세요.변경됨[attr]; 이것을 삭제하세요._pending[attr]; } } // 변경 이벤트에 바인딩된 함수를 트리거하는 변경 메서드를 호출합니다. if(!options.silent) this.change(옵션); 이거 돌려줘; }, //현재 모델에서 지정된 데이터를 삭제합니다. (속성도 동시에 삭제됩니다.) unset : 함수(속성, 옵션) { (옵션 || (옵션 = {})).unset = true; // options.unset 구성 항목을 통해 삭제 작업을 수행하도록 set 메소드에 알립니다. return this.set(attr, null, options); }, // 현재 모델의 모든 데이터와 속성을 지웁니다. 클리어 : 기능(옵션) { (옵션 || (옵션 = {})).unset = true; // 현재 모델의 속성 복사본을 복제하고, options.unset 구성 항목을 통해 삭제 작업을 수행하도록 set 메서드에 지시합니다. return this.set(_.clone(this.attributes), options); }, // 서버에서 기본 모델 데이터를 가져옵니다. 데이터를 가져온 후 set 메소드를 사용하여 데이터를 모델에 채웁니다. 따라서 가져온 데이터가 현재 모델의 데이터와 일치하지 않으면 변경 이벤트가 트리거됩니다. . 가져오기 : 함수(옵션) { // options가 새 객체인지 확인한 다음 options의 속성을 변경합니다. 옵션 = 옵션 ? _.clone(옵션) : {}; var 모델 = 이것; // 옵션에서 데이터를 성공적으로 얻은 후 사용자 정의 콜백 함수를 지정할 수 있습니다. var 성공 = options.success; // 데이터를 성공적으로 가져오면 데이터를 입력하고 사용자 정의 성공 콜백 함수를 호출합니다. options.success = function(resp, 상태, xhr) { // 서버가 반환한 데이터를 파싱 메소드를 통해 변환 // 변환된 데이터를 set 메소드를 통해 모델에 채워서 변경 이벤트가 발생하도록 합니다. (데이터가 변경될 때) // 데이터를 채울 때 유효성 검사에 실패하면 사용자 정의 성공 콜백 함수가 호출되지 않습니다. if(!model.set(model.parse(resp, xhr), 옵션)) 거짓을 반환; //사용자 정의 성공 콜백 함수 호출 만약(성공) 성공(모델, 담당자); }; // 요청에 오류가 발생하면 WrapError를 통해 오류 이벤트를 처리합니다. options.error = Backbone.wrapError(options.error, 모델, 옵션); // 서버에서 데이터를 가져오기 위해 동기화 메소드를 호출합니다. return (this.sync || Backbone.sync).call(this, 'read', this, options); }, //모델의 데이터를 서버에 저장 저장 : 함수(키, 값, 옵션) { // attrs는 서버에 저장해야 하는 데이터 객체를 저장합니다. var 속성, 현재; //단일 속성 키 설정 지원: value // 객체 형태의 {key: value} 일괄 설정 방법 지원 if(_.isObject(key) || 키 == null) { // 키가 객체인 경우 객체 메소드를 통해 설정되는 것으로 간주됩니다. // 이때 두 번째 매개변수는 옵션으로 간주됩니다. 속성 = 키; 옵션 = 가치; }또 다른 { // 단일 속성이 key:value 형식으로 설정된 경우 attrs를 직접 설정합니다. 속성 = {}; attrs[키] = 값; } // 구성 객체는 새로운 객체여야 합니다. 옵션 = 옵션 ? _.clone(옵션) : {}; // 옵션에 대기 옵션이 설정되어 있으면 변경된 데이터를 미리 검증하여 서버가 새로운 데이터에 응답하지 않거나 응답이 실패하는 경우 로컬 데이터를 수정 전 상태로 복원합니다. // wait 옵션이 설정되지 않은 경우 서버 설정 성공 여부와 관계없이 로컬 데이터는 최신 상태로 수정됩니다. if(options.wait) { // 저장해야 할 데이터를 미리 확인한다 if(!this._validate(속성, 옵션)) 거짓을 반환; //현재 모델에 데이터를 기록하며, 데이터를 서버로 전송한 후 복원하는 데 사용됩니다. // 서버 응답이 실패하거나 데이터가 반환되지 않는 경우 수정 전 상태를 유지할 수 있습니다. 현재 = _.clone(this.attributes); } // SilentOptions는 옵션 개체에 자동을 추가합니다(데이터 확인 없음). // 위에서 데이터가 검증되었으므로 wait 파라미터 사용 시 SilentOptions 구성 항목을 사용합니다. // wait 매개변수가 설정되지 않은 경우 원래 옵션 구성 항목이 계속 사용됩니다. var SilentOptions = _.extend({}, 옵션, { 침묵 : 사실 }); // 가장 최근에 수정된 데이터를 모델에 저장하여, 모델 데이터를 sync 메소드로 얻어 서버에 저장할 수 있도록 합니다. if(attrs && !this.set(attrs, options.wait ? SilentOptions : options)) { 거짓을 반환; } var 모델 = 이것; // 옵션에서 데이터를 성공적으로 저장한 후 사용자 정의 콜백 함수를 지정할 수 있습니다. var 성공 = options.success; //서버가 성공적으로 응답한 후 성공 실행 options.success = function(resp, 상태, xhr) { // 서버 응답의 최신 상태 데이터를 가져옵니다. var serverAttrs = model.parse(resp, xhr); // wait 매개변수를 사용하면 수정된 데이터 상태가 먼저 모델에 직접 설정됩니다. if(options.wait) { 옵션 삭제.잠깐; serverAttrs = _.extend(attrs || {}, serverAttrs); } //최신 데이터 상태를 모델에 설정 // set 메소드 호출 시 검증에 실패하면 커스텀 성공 콜백 함수가 호출되지 않습니다. if(!model.set(serverAttrs, 옵션)) 거짓을 반환; 만약(성공) { //응답이 성공한 후 맞춤형 성공 콜백 함수를 호출합니다. 성공(모델, 담당자); } 또 다른 { // 사용자 정의 콜백이 지정되지 않은 경우 기본적으로 동기화 이벤트가 트리거됩니다. model.trigger('sync', 모델, resp, 옵션); } }; // 요청에 오류가 발생하면 WrapError를 통해 오류 이벤트를 처리합니다. options.error = Backbone.wrapError(options.error, 모델, 옵션); //모델의 데이터를 서버에 저장 // 현재 모델이 새로 생성된 모델(id 없음)이면 create 메소드(new)를 사용하고, 그렇지 않으면 update 메소드(modified)로 간주합니다. var 메소드 = this.isNew() ? '생성': '업데이트'; var xhr = (this.sync || Backbone.sync).call(this, 메소드, this, 옵션); // options.wait가 설정되어 있으면 데이터를 수정 전 상태로 복원합니다. // 저장된 요청은 현재 응답을 받지 못했기 때문에 응답이 실패할 경우 모델은 수정 전 상태를 유지하게 되며, 서버가 성공적으로 응답하면 모델 내의 데이터는 성공 시 최신 상태로 설정됩니다. . if(옵션.기다림) this.set(current, SilentOptions); xhr을 반환합니다. }, //모델 삭제, 모델이 속한 컬렉션에서 모델이 삭제됩니다. // 클라이언트에서 모델이 생성된 경우 클라이언트에서 직접 삭제합니다. // 모델 데이터가 서버에 동시에 존재할 경우, 서버측 데이터도 동시에 삭제됩니다. 파괴 : 기능(옵션) { // 구성 항목은 새로운 객체여야 합니다. 옵션 = 옵션 ? _.clone(옵션) : {}; var 모델 = 이것; // 옵션에서 데이터가 성공적으로 삭제된 후 사용자 정의 콜백 함수를 지정할 수 있습니다. var 성공 = options.success; // 데이터 삭제를 위해 성공적으로 호출되면 소멸 이벤트가 트리거됩니다. 모델이 컬렉션에 존재하는 경우 컬렉션은 소멸 이벤트를 수신하고 트리거될 때 컬렉션에서 모델을 제거합니다. // 모델 삭제 시 모델 안의 데이터가 지워지지 않은 상태인데, 해당 모델이 컬렉션에서 제거되었기 때문에 해당 모델에 대한 참조가 어디에도 없으면 자동으로 메모리에서 해제됩니다. // 모델 삭제 시 모델 객체의 참조 변수를 null로 설정하는 것을 권장합니다. var TriggerDestroy = 함수() { model.trigger('파괴', 모델, model.collection, 옵션); }; // 모델이 클라이언트에서 새로 생성한 모델인 경우, TriggerDestroy를 직접 호출하여 컬렉션에서 해당 모델을 제거합니다. if(this.isNew()) { TriggerDestroy(); 거짓을 반환; }// 서버에서 데이터 삭제가 성공한 경우 options.success = 함수(resp) { // 옵션 객체에 대기 항목이 구성되어 있으면 서버 데이터가 성공적으로 삭제된 후 로컬 메모리에 있는 모델 데이터가 삭제된다는 의미입니다. // 서버 응답이 실패하면 로컬 데이터는 삭제되지 않습니다. if(옵션.기다림) TriggerDestroy(); 만약(성공) { //사용자 정의 성공 콜백 함수 호출 성공(모델, 담당자); } 또 다른 { // 커스텀 콜백이 없으면 기본적으로 동기화 이벤트가 트리거됩니다. model.trigger('sync', 모델, resp, 옵션); } }; // 요청에 오류가 발생하면 WrapError를 통해 오류 이벤트를 처리합니다. options.error = Backbone.wrapError(options.error, 모델, 옵션); //동기화 메소드를 통해 데이터 삭제 요청을 보냅니다. var xhr = (this.sync || Backbone.sync).call(this, '삭제', this, 옵션); // 옵션 객체에 대기 항목이 구성되어 있지 않으면 로컬 데이터를 먼저 삭제한 후 서버 데이터를 삭제하라는 요청을 보냅니다. // 이때, 서버 삭제 성공 여부와 상관없이 로컬 모델 데이터는 삭제된 상태입니다. if(!options.wait) TriggerDestroy(); xhr을 반환합니다. }, // 서버 인터페이스에서 모델에 해당하는 URL을 가져옵니다. save, fetch, destroy 및 기타 메소드를 호출하여 서버와 상호작용할 때 이 메소드를 사용하여 URL을 가져옵니다. // 생성된 URL은 "PATHINFO" 모드와 유사합니다. 서버에는 모델 작업을 위한 URL이 하나만 있습니다. 수정 및 삭제 작업의 경우 쉽게 식별할 수 있도록 모델 ID가 URL에 추가됩니다. // 모델에 urlRoot가 정의된 경우 서버 인터페이스는 [urlRoot/id] 형식이어야 합니다. // 모델이 속한 컬렉션이 url 메서드나 속성을 정의하는 경우 컬렉션에서 url 형식을 사용합니다: [collection.url/id] // 서버 URL에 액세스할 때 모델 ID가 URL에 추가되어 서버가 레코드를 쉽게 식별할 수 있으므로 모델의 ID는 서버 레코드와 일치해야 합니다. // 모델이나 컬렉션의 URL을 얻을 수 없으면 urlError 메서드가 호출되고 예외가 발생합니다. // 서버 인터페이스가 "PATHINFO"에 따라 구성되지 않은 경우 url 메서드를 오버로드하여 서버와 원활한 상호 작용을 구현할 수 있습니다. URL : 함수() { //서버에 해당하는 URL 경로를 정의합니다. var base = getValue(this, 'urlRoot') || getValue(this.collection, 'url') || // 현재 모델이 클라이언트에서 새로 생성한 모델인 경우 id 속성이 없고, 서버 url이 base를 직접 사용합니다. if(this.isNew()) 반환 기지; // 현재 모델에 id 속성이 있는 경우 save 또는 destroy 메소드가 호출될 수 있으며 모델의 id가 기본에 추가됩니다. //다음은 base의 마지막 문자가 "/"인지, 생성된 URL 형식이 [base/id]인지 확인합니다. return base (base.charAt(base.length - 1) == '/' ? '' : '/') encodeURIComponent(this.id); }, // 서버에서 가져온 데이터를 파싱하고 set 메서드로 파싱할 수 있는 모델 데이터를 반환하기 위해 파싱 메소드를 사용합니다. // 일반적으로 서버와의 원활한 연결을 구축하기 위해 서버에서 반환하는 데이터를 기반으로 구문 분석 메서드가 오버로드됩니다. // 서버가 반환한 데이터 구조가 set 메소드에서 요구하는 데이터 구조와 일치하지 않는 경우(예: 서버가 XML 형식의 데이터를 반환하는 경우) 변환에 구문 분석 메소드를 사용할 수 있습니다. 구문 분석 : 함수(resp, xhr) { 반환 응답; }, // 현재 모델과 동일한 데이터로 새 모델을 생성합니다. 복제 : 함수() { 새로운 this.constructor(this.attributes)를 반환합니다. }, // 현재 모델이 클라이언트가 생성한 새로운 모델인지 확인 // 확인 방법은 모델에 ID 식별자가 있는지 여부에 따라 결정됩니다. 클라이언트가 만든 새 모델에는 ID 식별자가 없습니다. // 따라서 서버가 응답하는 모델 데이터에는 id 식별자가 포함되어야 합니다. 식별자의 속성 이름은 기본적으로 "id"로 설정됩니다. idAttribute 속성을 수정하여 식별자를 맞춤 설정할 수도 있습니다. isNew : 함수() { return this.id == null; }, // 데이터가 업데이트될 때 변경 이벤트 바인딩을 트리거하는 함수 // set 메소드 호출 시 자동으로 변경 메소드가 호출됩니다. set 메소드 호출 시 자동 구성이 지정된 경우에는 변경 메소드를 수동으로 호출해야 합니다. 변경 : 기능(옵션) { // 옵션은 객체여야 합니다. 옵션 || ( 옵션 = {}); // 이와 관련된 로직에 문제가 있습니다._변경 // this._changing은 메서드 끝에서 false로 설정되므로 메서드 위의 변경 변수 값은 항상 false입니다(처음은 정의되지 않음). // 작성자의 원래 의도는 이 변수를 사용하여 변경 메서드가 실행되었는지 여부를 나타내는 것이어야 합니다. 이 메서드는 실행 시 다른 스크립트를 차단하므로 브라우저 측의 단일 스레드 스크립트에는 의미가 없습니다. // 변경하면 마지막 실행 상태를 가져옵니다. 마지막 스크립트가 실행되지 않은 경우 값은 true입니다. var 변경 = this._changing; //플래그 실행을 시작합니다. 실행 중 값은 항상 true입니다. 실행 후에는 this._changing이 false로 수정됩니다. this._changing = true; //이 변경 사항 이외의 데이터 상태를 _pending 개체에 추가합니다. for(this._silent의 var 속성) this._pending[attr] = true; // 변경 객체에는 현재 데이터에 대해 변경 이벤트가 마지막으로 실행된 이후 변경된 모든 데이터가 포함됩니다. // 이전에 자동을 사용하여 변경 이벤트가 트리거되지 않은 경우 이번에는 변경 객체에 배치됩니다. var 변경 = _.extend({}, options.changes, this._silent); //_silent 객체 재설정 this._silent = {}; // 변경 객체를 탐색하고 각 속성에 대해 별도의 변경 이벤트를 트리거합니다. for(변경 사항의 var 속성) { // Model 객체, 속성 값, 구성 항목을 이벤트 수신 함수에 매개변수로 전달합니다. this.trigger('change:' attr, this, this.get(attr), options); } //메소드가 실행 중이면 실행을 중지합니다. 만약(변경) 이거 돌려줘; // 변경 이벤트를 트리거합니다. 데이터가 변경된 후 "change:property" 이벤트와 "change" 이벤트가 차례로 트리거됩니다. while(!_.isEmpty(this._pending)) { this._pending = {}; // 변경 이벤트를 트리거하고 모델 인스턴스 및 구성 항목을 매개변수로 청취 함수에 전달합니다. this.trigger('change', this, options); // 변경된 객체의 데이터를 순회하고 변경된 데이터의 상태를 차례로 변경된 항목에서 제거합니다. // 이후 데이터 상태를 확인하기 위해 hasChanged를 호출하면 false(변경되지 않음)가 반환됩니다. for(this.changed의 var 속성) { if(this._pending[attr] || this._silent[attr]) 계속하다; //변경된 데이터의 상태를 제거합니다. 이것을 삭제하세요.변경됨[attr]; } // 변경 이벤트가 실행된 후 _previousAttributes 속성은 현재 모델의 최신 데이터 복사본을 기록합니다. // 따라서 데이터의 이전 상태를 가져와야 하는 경우 일반적으로 트리거된 변경 이벤트의 이전 또는 이전 속성 메서드를 통해서만 가져올 수 있습니다. this._previousAttributes = _.clone(this.attributes); } //실행 완료 플래그 this._changing = false; 이거 돌려줘; }, // 마지막 변경 이벤트가 실행된 이후 특정 데이터가 변경되었는지 확인합니다. /*** 일반적으로 다음과 같이 변경 이벤트에서 이전 또는 이전 속성 메서드와 함께 사용됩니다. * if(model.hasChanged('attr')) { * var attrPrev = model.previous('attr'); * }*/ hasChanged : 함수(attr) { if(!arguments.length) return !_.isEmpty(this.changed); return _.has(this.changed, attr); }, // 현재 모델의 데이터 컬렉션과 마지막 데이터에서 변경된 데이터를 가져옵니다. // (일반적으로 자동 속성 사용 시에는 변경 메소드가 호출되지 않으므로 변경된 속성에 데이터가 임시 저장됩니다. 마지막 데이터는 이전 속성 메소드를 통해 얻을 수 있습니다.) // diff 세트가 전달되면 마지막 모델 데이터가 diff 세트의 데이터와 비교되어 일치하지 않는 데이터 세트가 반환됩니다. // 비교 결과 차이가 없으면 false를 반환 변경된 속성: 함수(diff) { // diff를 지정하지 않으면 이전 상태에서 변경된 현재 모델의 데이터 컬렉션이 반환됩니다. 이러한 데이터는 변경된 속성에 저장되어 있으므로 변경된 컬렉션의 복사본이 반환됩니다. if(!차이점) return this.hasChanged() ? _.clone(this.changed) : false; // 비교해야 할 diff 세트를 지정하고 마지막 데이터와 diff 세트의 비교 결과를 반환합니다. //이전 변수는 이전 상태의 모델 데이터를 저장합니다. var val, 변경됨 = false, old = this._previousAttributes; // diff 컬렉션을 탐색하고 각 항목을 이전 상태 컬렉션과 비교합니다. for(diff의 var 속성) { // 비교 결과가 일치하지 않는 데이터를 변경된 변수에 임시 저장 if(_.isEqual(old[attr], ( val = diff[attr]))) 계속하다; (변경됨 || (변경됨 = {}))[attr] = val; } // 비교 결과를 반환 반품이 변경되었습니다. }, // 모델에 의해 발생된 변경 이벤트에서 속성이 변경되기 전의 이전 상태의 데이터를 획득하는데, 이는 일반적으로 데이터 비교나 롤백에 사용됩니다. // 이 메소드는 일반적으로 변경 이벤트에서 호출됩니다. 변경 이벤트가 트리거된 후 _previousAttributes 속성은 최신 데이터를 저장합니다. 이전 : 함수(속성) { // attr은 이전 상태를 가져오는 데 필요한 속성 이름을 지정합니다. if(!arguments.length || !this._previousAttributes) null을 반환; return this._previousAttributes[attr]; }, // 모델이 변경 이벤트를 트리거하면 모든 속성의 이전 상태에 대한 데이터 수집을 얻습니다. // 이 메소드는 이전() 메소드와 유사하며 일반적으로 변경 이벤트에서 호출되며 데이터 비교 또는 롤백에 사용됩니다. 이전 속성: function() { // 이전 상태의 데이터 객체를 새 객체로 복제하고 반환합니다. return _.clone(this._previousAttributes); }, // 현재 모델이 유효한 상태인지 확인하는 것만 가능합니다. // 자동 변경을 사용하는 경우 *invalid* 상태가 됩니다. // 현재 모델의 데이터가 유효성 검사 메서드로 검증 가능한지 확인합니다. 호출하기 전에 유효성 검사 메서드가 정의되어 있는지 확인하세요. isValid : 함수() { return !this.validate(this.attributes); }, // 데이터 검증 메소드는 설정, 저장, 추가 및 기타 데이터 업데이트 메소드를 호출할 때 자동으로 실행됩니다. // 검증에 실패하면 모델 객체의 "error" 이벤트가 발생합니다. 옵션에 오류 처리 함수가 지정되어 있으면 options.error 함수만 실행됩니다. // @param {Object}는 모델의 객체화된 데이터를 저장하는 데이터 모델의 속성을 나타냅니다. // @param {Object} 옵션 구성 항목 // @return {Boolean} 확인에 성공하면 true를 반환하고, 실패하면 false를 반환합니다. _validate : 함수(속성, 옵션) { // set, save, add 등의 데이터 업데이트 메소드를 호출할 때 options.silent 속성을 설정하면 검증이 무시됩니다. // 모델에 유효성 검사 메서드가 추가되지 않은 경우 유효성 검사가 무시됩니다. if(options.silent || !this.validate) 사실을 반환; // 객체의 모든 속성 값을 가져와 검증을 위해 검증 메소드에 넣습니다. //검증 방법에는 모델의 데이터 수집 및 구성 개체인 두 개의 매개 변수가 포함됩니다. 검증에 성공하면 데이터가 반환되지 않습니다(기본값은 정의되지 않음). 검증에 실패하면 오류 정보가 포함된 데이터가 반환됩니다. . attrs = _.extend({}, this.attributes, attrs); var error = this.validate(attrs, options); //확인 통과 만약(!오류) 사실을 반환; // 확인 실패 // 구성 개체에 오류 오류 처리 방법이 설정된 경우 이 메서드를 호출하고 오류 데이터 및 구성 개체를 이 메서드에 전달합니다. if(옵션 && options.error) { options.error(this, 오류, 옵션); } 또 다른 { // 오류 이벤트 리스너가 모델에 바인딩된 경우 바인딩 이벤트가 트리거됩니다. this.trigger('error', this, error, options); } //반품 확인 실패 식별 거짓을 반환; } }); // Backbone.Collection 데이터 모델 컬렉션 관련 //------ // 컬렉션은 동일한 클래스의 일련의 데이터 모델을 저장하고 모델을 작동하기 위한 관련 메서드를 제공합니다. var Collection = Backbone.Collection = function(모델, 옵션) { //구성 객체 옵션 || (옵션 = {}); //구성 매개변수에서 컬렉션의 모델 클래스를 설정합니다. if(옵션.모델) this.model = 옵션.모델; // comparator 속성이 설정되면 컬렉션의 데이터는 comparator 메소드의 정렬 알고리즘에 따라 정렬됩니다. (add 메소드에서 자동으로 호출됩니다.) if(옵션.비교기) this.comparator = 옵션.comparator; //인스턴스화 시 컬렉션의 내부 상태를 재설정합니다. (첫 번째 호출은 정의 상태로 이해될 수 있습니다.) this._reset(); // 사용자 정의 초기화 메소드를 호출합니다. 필요한 경우 일반적으로 초기화 메소드가 오버로드됩니다. this.initialize.apply(this, 인수); // 모델 데이터가 지정된 경우 재설정 메서드를 호출하여 컬렉션에 데이터를 추가합니다. // 처음 호출될 때 자동 매개변수가 설정되므로 "reset" 이벤트가 트리거되지 않습니다. if(모델) this.reset(모델, { 침묵 : 사실, 구문 분석 : 옵션.parse }); }; // 확장 메소드를 통해 컬렉션 클래스의 프로토타입 메소드를 정의합니다. _.extend(Collection.prototype, 이벤트, { // 컬렉션의 모델 클래스를 정의합니다. 모델 클래스는 Backbone.Model의 하위 클래스여야 합니다. // 컬렉션 관련 메소드(add, create 등) 사용 시 데이터 객체 전달이 허용됩니다. 컬렉션 메소드는 정의된 모델 클래스에 따라 해당 인스턴스를 자동으로 생성합니다. //컬렉션에 저장된 데이터 모델은 모두 동일한 모델 클래스의 인스턴스여야 합니다. 모델 : 모델, // 초기화 메서드, 이 메서드는 컬렉션 인스턴스가 생성된 후 자동으로 호출됩니다. // 이 메서드는 일반적으로 컬렉션 클래스를 정의할 때 오버로드됩니다. 초기화 : 함수() { }, // 컬렉션에 있는 각 모델의 데이터 객체를 포함하는 배열을 반환합니다. toJSON : 함수(옵션) { // Undersocre의 map 메소드를 사용하여 컬렉션의 각 모델에 대한 toJSON 결과 배열을 구성하고 반환합니다. return this.map(함수(모델) { // 각 모델 객체의 toJSON 메소드를 차례로 호출합니다. 이 메소드는 기본적으로 모델의 데이터 객체(복사본)를 반환합니다. // 문자열이나 다른 형식을 반환해야 하는 경우 toJSON 메서드를 오버로드할 수 있습니다. return model.toJSON(옵션); }); }, //하나 이상의 모델 객체를 컬렉션에 추가합니다. // "add" 이벤트는 기본적으로 발생합니다. 옵션에 자동 속성이 설정된 경우 이 이벤트 발생을 끌 수 있습니다. // 전달된 모델은 하나 또는 일련의 모델 개체(Model 클래스의 인스턴스)일 수 있습니다. 모델 속성이 컬렉션에 설정된 경우 데이터 개체(예: {name: 'test'})가 허용됩니다. 모델이 가리키는 모델 객체로 데이터 객체를 자동으로 인스턴스화합니다. 추가 : 기능(모델, 옵션) { //지역변수 정의 var i, 인덱스, 길이, 모델, cid, id, cids = {}, ids = {}, dups = []; 옵션 || (옵션 = {}); // 모델은 배열이어야 하며, 하나의 모델만 전달된 경우 배열로 변환합니다. models = _.isArray(models) ? models.slice() : [모델]; // 추가해야 할 모델 목록을 순회하는 동안 다음 작업이 수행됩니다. // - 데이터 객체를 모델 객체로 변환 // - 모델과 컬렉션 사이에 참조를 설정합니다. // - 유효하지 않은 모델과 중복된 모델을 기록하고 나중에 필터링합니다. for( i = 0, 길이 = models.length; i