ব্যাকবোন.জেএস ভিউগুলিতে আইডি এবং ক্লাসনেম গতিশীলভাবে সেট করা হচ্ছে


85

আমি ব্যাকবোন.জেএস শেখার এবং ব্যবহার করার প্রক্রিয়াধীন।

আমার কাছে একটি আইটেম মডেল এবং সংশ্লিষ্ট আইটেম ভিউ রয়েছে। প্রতিটি মডেলের উদাহরণের আইটেম_ক্লাস এবং আইটেম_আইডি বৈশিষ্ট্য রয়েছে যা আমি সংশ্লিষ্ট ভিউর 'আইডি' এবং 'শ্রেণি' বৈশিষ্ট্য হিসাবে প্রতিবিম্বিত হতে চাই। এটি অর্জনের সঠিক উপায় কী?

উদাহরণ:

var ItemModel = Backbone.Model.extend({      
});

var item1 = new ItemModel({item_class: "nice", item_id: "id1"});
var item2 = new ItemModel({item_class: "sad", item_id: "id2"});

var ItemView = Backbone.View.extend({       
});

আমার দৃষ্টিভঙ্গিটি কীভাবে বাস্তবায়ন করা উচিত যাতে দর্শনগুলির এলগুলি অনুবাদ করে:

<div id="id1" class="nice"></div>
<div id="id2" class="sad"> </div>

বেশিরভাগ উদাহরণগুলিতে আমি দেখেছি, ভিউ এর এল একটি অর্থহীন মোড়কের উপাদান হিসাবে কাজ করে যার মধ্যে একজনকে ম্যানুয়ালি 'শব্দার্থিক' কোড লিখতে হয়।

var ItemView = Backbone.View.extend({
   tagName:  "div",   // I know it's the default...

   render: function() {
     $(this.el).html("<div id="id1" class="nice"> Some stuff </div>");
   }       
});

সুতরাং যখন রেন্ডার করা হয়, একজন পায়

<div> <!-- el wrapper -->
    <div id="id1" class="nice"> Some stuff </div>
</div>

তবে এটিকে বর্জ্য মনে হচ্ছে - বাহ্যিক ডিভ কেন? আমি এলটি সরাসরি অভ্যন্তরীণ ডিভ অনুবাদ করতে চাই !

উত্তর:


133

সংক্ষিপ্তসার: গতিশীলভাবে মডেল ডেটা সহ দৃশ্য বৈশিষ্ট্যগুলি সেট করুন

http://jsfiddle.net/5wd0ma8b/

// View class with `attributes` method
var View = Backbone.View.extend( {
  attributes : function () {
    // Return model data
    return {
      class : this.model.get( 'item_class' ),
      id : this.model.get( 'item_id' )
    };
  }
  // attributes
} );

// Pass model to view constructor
var item = new View( {
  model : new Backbone.Model( {
    item_class : "nice",
    item_id : "id1"
  } )
} );
  • এই উদাহরণটি ধরে নিয়েছে যে আপনি ব্যাকবোনকে আপনার জন্য একটি ডিওএম উপাদান তৈরি করতে দিচ্ছেন।

  • attributesপরে বৈশিষ্ট্য দেখতে কন্সট্রাকটর প্রেরণ নির্ধারণ করা হয় পদ্ধতি বলা হয় (এই ক্ষেত্রে, model), আপনি পরিবর্তনশীল মডেল ডেটার সাথে বৈশিষ্ট্যাবলী সামনে দাঁড়া সৃষ্টি সেট করতে সক্ষম হবেন el

  • অন্যান্য উত্তরগুলির বিপরীতে: ভিউ ক্লাসে হার্ড-কোড অ্যাট্রিবিউট মানগুলি গতিশীলভাবে মডেল ডেটা থেকে সেট করে না; render()অ্যাটর ভ্যালস সেট না হওয়া পর্যন্ত অপেক্ষা করবেন না ; বারবার প্রতিটি কলে এট্রে ভ্যালস সেট করে না render(); অযৌক্তিকভাবে ডিওএম উপাদানটিতে অ্যাটর ভ্যালস সেট করে না।

  • নোট করুন যে কল করার সময় শ্রেণি নির্ধারণ করা Backbone.View.extendবা কোনও ভিউ কনস্ট্রাক্টর (উদাহরণস্বরূপ new Backbone.View), আপনাকে ডিওএম সম্পত্তি নাম ব্যবহার করতে হবে className, তবে attributesহ্যাশ / পদ্ধতির মাধ্যমে সেট করা থাকলে (এই উদাহরণ হিসাবে) আপনাকে বৈশিষ্ট্যটির নাম ব্যবহার করতে হবে class,।

  • ব্যাকবোন 0.9.9 হিসাবে:

    যখন কোনো দৃশ্য ঘোষণা ... el, tagName, idএবং classNameএখন ফাংশন হিসাবে সংজ্ঞায়িত করা যেতে পারে, যদি আপনি চান তাহলে তাদের মান রানটাইম এ নির্ধারণ করতে হবে।

    আমি এটি উল্লেখ করেছি যদি এমন কোনও পরিস্থিতি থাকে যেখানে attributesচিত্রিত হিসাবে কোনও পদ্ধতি ব্যবহারের বিকল্প হিসাবে এটি কার্যকর হয় ।

একটি বিদ্যমান উপাদান ব্যবহার করে

যদি আপনি একটি বিদ্যমান উপাদান ব্যবহার করে থাকেন (উদাহরণস্বরূপ elভিউ কনস্ট্রাক্টরের কাছে যাচ্ছেন ) ...

var item = new View( { el : some_el } );

... তাহলে attributesউপাদানটিতে প্রয়োগ করা হবে না। পছন্দসই বৈশিষ্ট্য ইতিমধ্যে উপাদান সেট নাও হয়, অথবা আপনি আপনার দৃশ্য শ্রেণী এবং অন্য একটি অবস্থানে যে ডেটা প্রতিলিপি করতে চাই না, তাহলে আপনি একটি অ্যাড করতে পারেন initializeপ্রযোজ্য আপনার ভিউ কন্সট্রাকটর করার পদ্ধতি attributesথেকে el। এরকম কিছু (ব্যবহার করে jQuery.attr):

View.prototype.initialize = function ( options ) {
  this.$el.attr( _.result( this, 'attributes' ) );
};

elমোড়ক এড়ানো, রেন্ডারিং এর ব্যবহার

বেশিরভাগ উদাহরণগুলিতে আমি দেখেছি, ভিউ এর এল একটি অর্থহীন মোড়কের উপাদান হিসাবে কাজ করে যার মধ্যে একজনকে ম্যানুয়ালি 'শব্দার্থিক' কোড লিখতে হয়।

view.el"অর্থহীন মোড়কের উপাদান" হওয়ার কোনও কারণ নেই । আসলে, এটি প্রায়শই ডিওএম কাঠামোটিকে ভেঙে দেয়। <li>উদাহরণস্বরূপ যদি কোনও ভিউ ক্লাস কোনও উপাদানকে <li>উপস্থাপন করে তবে এটিকে একটি হিসাবে রেন্ডার করা দরকার - এটিকে <div>অন্য কোনও উপাদান হিসাবে উপস্থাপন করা সামগ্রীর মডেলটিকে ভেঙে দেবে। আপনি সম্ভবত সঠিকভাবে আপনার ভিউ এর উপাদান স্থাপনের (যেমন বৈশিষ্ট্য ব্যবহার ফোকাস করতে চাইবেন tagName, classNameএবং id) এবং তারপর তার রেন্ডারিং বিষয়বস্তু তারপরে।

আপনার ব্যাকবোন ভিউ অবজেক্টগুলি কীভাবে DOM এর সাথে ইন্টারঅ্যাক্ট করবেন তার বিকল্পগুলি খোলা রয়েছে। প্রাথমিক দুটি প্রাথমিক পরিস্থিতি রয়েছে:

  • আপনি একটি বিদ্যমান ডোম উপাদান একটি ব্যাকবোন ভিউতে সংযুক্ত করতে পারেন।

  • আপনি ব্যাকবোনকে একটি নতুন উপাদান তৈরি করতে অনুমতি দিতে পারেন যা দস্তাবেজ থেকে সংযোগ বিচ্ছিন্ন হয়ে গেছে, তারপরে কোনওভাবে এটি নথিতে সন্নিবেশ করানো উচিত।

উপাদানটির জন্য আপনি সামগ্রী তৈরি করতে পারেন এমন বিভিন্ন উপায় রয়েছে (আপনার উদাহরণের মতো একটি আক্ষরিক স্ট্রিং সেট করুন; গোঁফ, হ্যান্ডলবারস, ইত্যাদির মতো একটি টেম্প্লেটিং লাইব্রেরি ব্যবহার করুন)। আপনার কীভাবে elদেখার সম্পত্তিটি ব্যবহার করা উচিত তা নির্ভর করে আপনি কী করছেন।

বিদ্যমান উপাদান

আপনার রেন্ডারিং উদাহরণটি পরামর্শ দেয় যে আপনার কাছে বিদ্যমান উপাদান রয়েছে যা আপনি দৃশ্যের জন্য নির্ধারিত করছেন, যদিও আপনি দর্শনগুলি ইনস্ট্যান্টেশন দেখান না। যদি এটি হয়, এবং উপাদানটি নথিতে ইতিমধ্যে রয়েছে, তবে আপনি এটির মতো কিছু করতে চাইতে পারেন (এর বিষয়বস্তু আপডেট করুন el, তবে elনিজেই পরিবর্তন করবেন না ):

render : function () {
  this.$el.html( "Some stuff" );
}

http://jsfiddle.net/vQMa2/1/

উত্পন্ন উপাদান

ধরা যাক আপনার কোনও বিদ্যমান উপাদান নেই এবং আপনি ব্যাকবোনকে আপনার জন্য একটি উত্পন্ন করতে মঞ্জুরি দেন। আপনি এই জাতীয় কিছু করতে চাইতে পারেন (তবে সম্ভবত স্থপতি জিনিসগুলির চেয়ে এটি আরও ভাল যাতে আপনার দৃষ্টিভঙ্গি নিজের বাইরে কোনও কিছু জানার জন্য দায়বদ্ধ না হয়):

render : function () {
  this.$el.html( "Some stuff" );
  $( "#some-container" ).append( this.el );
}

http://jsfiddle.net/vQMa2/

টেম্পলেট

আমার ক্ষেত্রে, আমি টেমপ্লেটগুলি ব্যবহার করছি, উদাহরণস্বরূপ:

<div class="player" id="{{id}}">
<input name="name" value="{{name}}" />
<input name="score" value="{{score}}" />
</div>
<!-- .player -->

টেমপ্লেটটি সম্পূর্ণ দর্শনের প্রতিনিধিত্ব করে। অন্য কথায়, টেমপ্লেটের চারপাশে কোনও মোড়ক div.playerথাকবে না - এটি আমার দেখার মূল বা বহিরাগত উপাদান হবে।

আমার প্লেয়ার বর্গটি এর মতো দেখতে পাবেন (এর খুব সরল উদাহরণ সহ render()):

Backbone.View.extend( {
  tagName : 'div',
  className : 'player',

  attributes : function () {
    return {
      id : "player-" + this.model.cid
    };
  },
  // attributes

  render : function {
    var rendered_template = $( ... );

    // Note that since the top level element in my template (and therefore
    // in `rendered_template`) represents the same element as `this.el`, I'm
    // extracting the content of `rendered_template`'s top level element and
    // replacing the content of `this.el` with that.
    this.$el.empty().append( rendered_template.children() );
  }      
} );

একটি ফাংশন সহ বৈশিষ্ট্য বৈশিষ্ট্যগুলিকে ওভাররাইট করার এবং আবার কোনও বস্তুকে ফেরত দেওয়ার দুর্দান্ত উপায়!
কেল

4
@ কেল হ্যাঁ, প্রশ্নগুলি যা জিজ্ঞাসা করে তার মত গতিশীল কিছু অর্জন করার একটি ভাল উপায়, যেখানে ভিউগুলি তাত্ক্ষণিকভাবে পুনরায় সংকেতযুক্ত কোড ব্যবহার না করে মডেল ডেটা দিয়ে বৈশিষ্ট্যগুলি জনপ্রিয় করে তোলা। আপনি সম্ভবত এটি জানেন, তবে কেবল এটি সুস্পষ্ট না হলে এটি ব্যাকবোনটির একটি বৈশিষ্ট্য যা আপনি একটি ফাংশন ব্যবহার করতে পারেন যা একটি হ্যাশকে মূল্য হিসাবে ফিরিয়ে দেয় attributes, যেমন অনেকগুলি ব্যাকবোন বৈশিষ্ট্য যা ফাংশন হিসাবে সরবরাহ করা যেতে পারে বা অন্য কোনও হিসাবে মান ধরনের। এই ক্ষেত্রে ব্যাকবোন মানটি কোনও ফাংশন কিনা তা পরীক্ষা করে, এটিকে কল করে এবং ফেরতের মানটি ব্যবহার করে।
জেএমএম

95

আপনার দৃষ্টিতে এই জাতীয় কিছু করুন

var ItemView = Backbone.View.extend({
   tagName:  "div",   // I know it's the default...

   render: function() {
     $(this.el).attr('id', 'id1').addClass('nice').html('Some Stuff'); 
   }       
});

এটি এই প্রশ্নের সঠিক উত্তর এবং এটি গ্রহণ করা উচিত
পৌঁছে যান 4

13
এই উত্তরটি মডেল ডেটার উপর ভিত্তি করে ভিউ বৈশিষ্ট্যগুলি গতিশীলভাবে সেট করে দেখায় না, এটি কেবলমাত্র বৈশিষ্ট্যটির মানগুলিকে কোডিংয়ের একটি বিকল্প পদ্ধতি দেখায়।
জেএমএম

4
@ জেএমএম - তার নমুনা কোডটি মডেল ডেটাও ব্যবহার করছে না। এই উত্তরটি তার নমুনা কোডের ভিত্তিতে কাজ করে। স্পষ্টতই মডেলের ডেটাগুলি মানগুলির জন্য প্রতিস্থাপন করা যেতে পারে।
ক্লিন্ট

4
@ ক্লিন্ট, আমি ওপিতে এটি সুস্পষ্ট বলে গণ্য করব না। "তার নমুনা কোডটি মডেল ডেটাও ব্যবহার করছে না।" - কারণ এটি কীভাবে তিনি জানেন না এবং তাই তিনি কেন সাহায্য চেয়েছিলেন। এটি আমার কাছে স্পষ্ট বলে মনে হচ্ছে যে তিনি মডেল ডেটা ব্যবহার করে ভিউ-এএল-এর সংস্থাগুলি কীভাবে সেট করবেন তা জিজ্ঞাসা করছেন এবং এটি কীভাবে করবেন সে সম্পর্কে কোনও ধারণা নেই। উত্তরটি কীভাবে এটি করতে পারে তাও দেখায় না এবং কেন আপনি যেভাবেই এটির উপস্থাপন না করা পর্যন্ত অপেক্ষা করবেন বা প্রতিবার আপনি যখন রেন্ডার করবেন তখন কেন তা আবার করবেন? "এই উত্তরটি কাজ করে ..." - এটি কীভাবে কাজ করে? এর মতো তৈরি প্রতিটি দর্শনে একই অ্যাটর ভ্যালস থাকবে। এটি কেবল দেখায় যে কীভাবে মোড়ক এড়ানো যায়।
জেএমএম

ফেব্রুয়ারী '12 থেকে ওপি চলে গেছে। :( এখানে এই উত্তরের জন্য অন্য +1 টি আছে।
Almo

27

আপনি বৈশিষ্ট্যগুলি classNameএবং idমূল উপাদানটিতে সেট করতে পারেন : http://docamentcloud.github.com/backbone/# ভিউ- এক্সেট

var ItemView = Backbone.View.extend({
   tagName:  "div",   // I know it's the default...
   className : 'nice',
   id : 'id1',
   render: function() {
     $(this.el).html("Some stuff");
   }       
});

EDIT কনস্ট্রাক্টর প্যারামিটারের উপর ভিত্তি করে আইডি সেট করার উদাহরণ অন্তর্ভুক্ত

উল্লিখিত মতামতগুলি যদি নির্মিত হয়:

var item1 = new ItemModel({item_class: "nice", item_id: "id1"});
var item2 = new ItemModel({item_class: "sad", item_id: "id2"});

তাহলে মানগুলি এইভাবে সেট করা যেতে পারে:

// ...
className: function(){
    return this.options.item_class;
},
id: function(){
    return this.options.item_id;
}
// ...

4
আমি এই উত্তরটি সঠিক কারণ তারপর প্রতি মনে হয় না ItemViewহবে id: 'id1'। এটি নির্ধারিত সময়ে নির্ধারিত সময়ে গণনা করতে হবে model.id
fguillen

আপনি অবশ্যই যেভাবে আইডি সেট করতে পারেন। একটি ফাংশন, পরিবর্তনশীল বা যে কোনও কিছু ব্যবহার করুন। মূল কোডটিতে কীভাবে মান সেট করা যায় তা নির্দেশ করে আমার কোডটিতে কেবল একটি উদাহরণ রয়েছে।
জর্জেন

কনস্ট্রাক্টর প্যারামিটারের উপর ভিত্তি করে কীভাবে মানগুলি গতিশীলভাবে সেট করতে হবে তা পরিষ্কার করার জন্য আমি একটি উদাহরণ যুক্ত করেছি।
জর্জেন

এটা সঠিক উত্তর. সমস্যাটি সমাধান করতে এটি ব্যাকবোন বৈশিষ্ট্যগুলি সঠিকভাবে ব্যবহার করে।
মার্ক-

6

আমি জানি এটি একটি পুরানো প্রশ্ন, তবে রেফারেন্সের জন্য যুক্ত হয়েছে। এটি নতুন ব্যাকবোন সংস্করণগুলিতে আরও সহজ বলে মনে হচ্ছে। ব্যাকবোন ১.১ এ আইডি এবং ক্লাসনেম বৈশিষ্ট্যগুলি ফাংশনে মূল্যায়ন করা হয় ensureElement( উত্স থেকে দেখুন ) আন্ডারস্কোর _.resultঅর্থ ব্যবহার করে classNameবা idযদি কোনও ফাংশন হয় তবে এটি ডাকা হবে, অন্যথায় এর মান ব্যবহার করা হবে।

সুতরাং আপনি সরাসরি কনস্ট্রাক্টরে ক্লাসের নাম দিতে পারতেন, ক্লাসের নাম ইত্যাদিতে ব্যবহৃত হবে এমন আরও একটি প্যারামিটার দিতে পারেন ... প্রচুর বিকল্প

সুতরাং এটি কাজ করা উচিত

var item1 = new ItemModel({item_class: "nice", item_id: "id1"});
var item2 = new ItemModel({item_class: "sad", item_id: "id2"});

var ItemView = Backbone.View.extend({       
  id: function() { return this.model.get('item_id'); },
  className: function() { return this.model.get('item_class'); }
});

আপনার উদাহরণটি বৈধ নয়, আপনি চাইবেনid: function() { return this.model.get('item_id'); })
কবি

4

অন্যান্য উদাহরণগুলি দেখানো হচ্ছে না কীভাবে মডেল থেকে ডেটা দখল করা যায়। মডেলের ডেটা থেকে আইডি এবং ক্লাসটি গতিশীলভাবে যুক্ত করতে:

var ItemView = Backbone.View.extend({
   tagName:  "div",

   render: function() {
     this.id = this.model.get('item_id');
     this.class = this.model.get('item_class');
     $(this.el).attr('id',this.id).addClass(this.class).html('Some Stuff'); 
   }       
});

এটি কি 'this.className' বা 'this.class'?
গ্যাবে রেইনবো

2

আপনার ট্যাগনাম সরিয়ে একটি এল ঘোষণা করতে হবে।

'ট্যাগনাম' ইঙ্গিত দেয় যে আপনি ব্যাকবোনটি একটি উপাদান তৈরি করতে চান। যদি ডিওমে ইতিমধ্যে উপাদান উপস্থিত থাকে তবে আপনি একটি এল নির্দিষ্ট করতে পারেন:

el: $('#emotions'),

এবং পরে:

render: function() { 
     $(this.el).append(this.model.toJSON());
}

2

ইনিশিয়াল পদ্ধতিতে মানগুলি নির্ধারণের চেষ্টা করুন এটি সরাসরি আই ডি এবং ক্লাসটি ডিভ অ্যাট্রিবিউটকে গতিশীলভাবে বরাদ্দ করবে।

var ItemView = Backbone.View.extend( {
    tagName : "div",   
    id      : '',
    class   : '',

    initialize : function( options ) {
        if ( ! _.isUndefined( options ) ) {
            this.id = options.item_id;
            this.class= options.item_class;
        }
    },

    render : function() {
        $( this.el ).html( this.template( "stuff goes here" ) ); 
    }
} );

@Michel Pleasae এই ডকুমেন্টেশন এর মধ্য দিয়ে যেতে, backbonejs.org/#View-constructor
Hemanth

0

একটি মডেলের মাধ্যমে দৃশ্যের সাথে ভিউটির উপাদানটির শ্রেণি পরিবর্তন করার এবং মডেল পরিবর্তনে এটি আপডেট করার একটি ন্যূনতম উপায়।

var VMenuTabItem = Backbone.View.extend({
    tagName: 'li',
    events: {
        'click': 'onClick'
    },
    initialize: function(options) {

        // auto render on change of the class. 
        // Useful if parent view changes this model (e.g. via a collection)
        this.listenTo(this.model, 'change:active', this.render);

    },
    render: function() {

        // toggle a class only if the attribute is set.
        this.$el.toggleClass('active', Boolean(this.model.get('active')));
        this.$el.toggleClass('empty', Boolean(this.model.get('empty')));

        return this;
    },
    onClicked: function(e) {
        if (!this.model.get('empty')) {

            // optional: notify our parents of the click
            this.model.trigger('tab:click', this.model);

            // then update the model, which triggers a render.
            this.model.set({ active: true });
        }
    }
});
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.