2016-03-29 9 views
0

Ich bin erfolgreich "Kontakt" Sobject Felder auf Visualforce-Seite mit backbone.js zu bekommen. Ich möchte sowohl Account- als auch Kontaktfelder zur gleichen Zeit und auf derselben Seite anzeigen. Um dies zu tun, sollte ich zwei Modelle für jedes Objekt oder zwei Sammlungen für jedes Objekt verwenden. Wenn ja, dann bitte etwas erklären. Bitte führen Sie mich, wie ich neu bei backbone.js bin. Hier ist mein Code.Salesforce: Wie erhält man Felder von zwei Objekten "Account" und "Kontakt" auf der Visualforce-Seite mit Backbone.js?

<apex:page docType="html-5.0" standardStylesheets="false" showHeader="false" sidebar="false"> 
<head> 
    <meta charset="UTF-8" /> 
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" /> 
    <meta name="viewport" content="width=device-width, initial-scale=1.0" /> 
    <title>Contacts in Backbone.js</title> 

    <!-- ========= --> 
    <!-- CSS --> 
    <!-- ========= --> 
    <link href="{!URLFOR($Resource.MobileSample_Resources_Backbone, 'resources/css/jquery.mobile-1.3.0.min.css')}" rel="stylesheet" /> 

    <!-- ========= --> 
    <!-- Libraries --> 
    <!-- ========= --> 
    <script src="{!URLFOR($Resource.MobileSample_Resources_Backbone, 'resources/lib/jquery-2.0.0.min.js')}" type="text/javascript"></script> 
    <script src="{!URLFOR($Resource.MobileSample_Resources_Backbone, 'resources/lib/underscore-1.4.4.min.js')}" type="text/javascript"></script> 
    <script src="{!URLFOR($Resource.MobileSample_Resources_Backbone, 'resources/lib/backbone-1.0.0.min.js')}" type="text/javascript"></script> 
    <script src="{!URLFOR($Resource.MobileSample_Resources_Backbone, 'resources/lib/forcetk.js')}" type="text/javascript"></script> 
    <script src="{!URLFOR($Resource.MobileSample_Resources_Backbone, 'resources/lib/force.entity.js')}" type="text/javascript"></script> 
    <script> 
    $(document).on("mobileinit", 
     // Set up the "mobileinit" handler before including jQuery Mobile 
     function() { 
     $.mobile.ajaxEnabled = false; 
     $.mobile.linkBindingEnabled = false; 
     } 
    ) 
    </script> 
    <script src="{!URLFOR($Resource.MobileSample_Resources_Backbone, 'resources/lib/jquerymobile.js')}" type="text/javascript"></script> 
</head> 
<body> 

    <!-- ========= --> 
    <!-- HTML CODE --> 
    <!-- ========= --> 
    <div id="contacts" data-role="page" data-title="Contacts"> 
    <div data-role="header"> 
     <h1>Contacts</h1> 
    </div><!-- /header --> 
    <div data-role="content" id="contacts-content"> 
    </div> 
    </div> 

    <div id="contact" data-role="page" data-title="Contact"> 
    <div data-role="header"> 
     <a href='#' id="back" class='ui-btn-left' data-icon='arrow-l'>Back</a> 
     <h1>Contact</h1> 
    </div><!-- /header --> 
    <div data-role="content" id="contact-content"> 
    </div> 
    </div> 

    <!-- ========= --> 
    <!-- Templates --> 
    <!-- ========= --> 
    <script type="text/template" id="contacts-template"> 
    <form> 
     <button data-role="button" class="new">New Contact</button> 
    </form> 
    <ul data-role="listview" data-inset="true" id="contact-list"> 
    </ul> 
    <div data-role="footer"> 
     <div data-role="fieldcontain"> 
     <label for="select-theme" class="select">UI Theme:</label> 
     <select class="theme-selector" name="select-theme" id="select-theme"> 
      <option value="default">default</option> 
      <option value="a">a</option> 
      <option value="b">b</option> 
      <option value="c">c</option> 
      <option value="d">d</option> 
      <option value="e">e</option> 
     </select> 
     </div> 
    </div> 
    </script> 

    <script type="text/template" id="contact-template"> 
    <% if (typeof(Id) !== 'undefined') { %> 
     <a href="#<%= Id %>"><%- Name %></a> 
    <% } else { %> 
     <%- Name %> 
    <% } %> 
    </script> 

    <script type="text/template" id="contact-detail-template"> 
    <form name="contactform" id="contactform"> 
     <% if (typeof(Id) !== 'undefined') { %> 
     <input type="hidden" name="Id" id="Id" value="<%- Id %>" /> 
     <% } %> 
     <div data-role="fieldcontain"> 
     <label for="Name">First Name:</label> 
     <% if (typeof(FirstName) !== 'undefined') { %> 
      <input name="FirstName" id="FirstName" value="<%- FirstName %>" /> 
     <% } else { %> 
      <input name="FirstName" id="FirstName" /> 
     <% } %> 
     </div> 
     <div data-role="fieldcontain"> 
     <label for="Name">Last Name:</label> 
     <% if (typeof(LastName) !== 'undefined') { %> 
      <input name="LastName" id="LastName" value="<%- LastName %>" /> 
     <% } else { %> 
      <input name="LastName" id="LastName" /> 
     <% } %> 
     </div> 
     <div data-role="fieldcontain"> 
     <label for="Email">Email:</label> 
     <% if (typeof(Email) !== 'undefined') { %> 
      <input name="Email" id="Email" value="<%- Email %>" /> 
     <% } else { %> 
      <input name="Email" id="Email" /> 
     <% } %> 
     </div> 
     <button data-role="button" data-icon="check" data-inline="true" data-theme="b" class="save">Save</button> 
     <% if (typeof(Id) !== 'undefined') { %> 
     <button data-role="button" data-icon="delete" data-inline="true" class="destroy">Delete</button> 
     <% } %> 
    </form> 
    </script> 

    <!-- =============== --> 
    <!-- Javascript code --> 
    <!-- =============== --> 
    <script type="text/javascript"> 


    function changeTheme(theme){ 
     var hfTheme = theme, 
      cTheme = theme; 

     if (theme === 'default') { 
     // "If no theme swatch letter is set at all, the framework uses the 
     // "a" swatch (black in the default theme) for headers and footers 
     // and the "c" swatch (light gray in the default theme) for the page 
     // content to maximize contrast between the both." 
     // http://jquerymobile.com/demos/1.2.1/docs/api/themes.html 
     hfTheme = "a"; 
     cTheme = "c"; 
     } 

     $.mobile.activePage.find('.ui-btn').not('.ui-li-divider') 
         .removeClass('ui-btn-up-a ui-btn-up-b ui-btn-up-c ui-btn-up-d ui-btn-up-e ui-btn-hover-a ui-btn-hover-b ui-btn-hover-c ui-btn-hover-d ui-btn- 

hover-e') 
         .addClass('ui-btn-up-' + cTheme) 
         .attr('data-theme', cTheme); 

     $.mobile.activePage.find('.ui-li-divider').each(function (index, obj) { 
     if ($(this).parent().attr('data-divider-theme') == 'undefined') { 
      $(this).removeClass('ui-bar-a ui-bar-b ui-bar-c ui-bar-d ui-bar-e') 
        .addClass('ui-bar-' + cTheme) 
        .attr('data-theme', cTheme); 
     } 
     }) 

     $.mobile.activePage.find('.ui-header, .ui-footer') 
         .removeClass('ui-bar-a ui-bar-b ui-bar-c ui-bar-d ui-bar-e') 
         .addClass('ui-bar-' + hfTheme) 
         .attr('data-theme', hfTheme); 
     $.mobile.activePage.removeClass('ui-body-a ui-body-b ui-body-c ui-body-d ui-body-e') 
         .addClass('ui-body-' + cTheme) 
         .attr('data-theme', cTheme); 
    } 

    $(document).ready(function() { 
     var creds = { 
     accessToken: '{!$Api.Session_ID}' 
     }; 

     Force.init(creds); 

     myapp(); 
    }); 

    function myapp() { 
     var app = {}; // create namespace for our app 

     //-------------- 
     // Models 
     //-------------- 
     app.Contact = Force.SObject.extend({ 
     sobjectType:'Contact', 
     fieldlist:['Id', 'FirstName', 'LastName', 'Email'] 
     }); 

     //-------------- 
     // Collections 
     //-------------- 
     app.ContactsCollection = Force.SObjectCollection.extend({ 
     model: app.Contact, 
     fieldlist:['Id', 'Name', 'FirstName', 'LastName', 'Email'], 
     config: function() { 
      return {type:"soql", query:"SELECT " + this.fieldlist.join(",") + " FROM Contact ORDER BY Name LIMIT 25"}; 
     } 
     }), 

     //-------------- 
     // Views 
     //-------------- 

     // renders individual Contact list item (li) 
     app.ContactView = Backbone.View.extend({ 
     tagName: 'li', 
     template: _.template($('#contact-template').html()), 
     render: function(){ 
      this.$el.html(this.template(this.model.toJSON())); 
      return this; // enable chained calls 
     }, 
     initialize: function(){ 
     } 
     }); 

     // renders individual Contact for editing 
     app.ContactDetailView = Backbone.View.extend({ 
     template: _.template($('#contact-detail-template').html()), 
     render: function(){ 
      this.$el.html(this.template(this.model.toJSON())); 
      return this; // enable chained calls 
     }, 
     initialize: function(){ 
      this.model.on('destroy', this.remove, this); 
      this.render(); 
     }, 
     events: { 
      'change' : 'change', 
      'click .save' : 'save', 
      'click .destroy': 'destroy' 
     }, 
     change: function (event) { 
      // Apply the change to the model 
      var target = event.target; 
      var change = {}; 
      change[target.name] = target.value; 
      this.model.set(change); 
     }, 
     save: function(){ 
      this.model.save(null, { 
      success: function(model) { 
       app.router.navigate('contacts', {trigger: true}); 
      }, 
      error: function() { 
       alert('Error saving'); 
      } 
      }); 
      return false; 
     }, 
     destroy: function(){ 
      this.model.destroy({ 
      success: function() { 
       app.router.navigate('contacts', {trigger: true});    
      }, 
       error: function() { 
       alert('Error deleting'); 
       } 
      }); 
      return false; 
     } 
     }); 

     // renders the full list of Contacts calling ContactView for each one. 
     app.ContactsView = Backbone.View.extend({ 
     template: _.template($('#contacts-template').html()), 
     initialize: function() { 
      this.render(); 
      this.model.on('add', this.render, this); 
      this.model.on('reset', this.render, this); 
     }, 
     events: { 
      'click .new' : 'newContact', 
      'change .theme-selector' : 'changeTheme' 
     }, 
     renderOne: function(contact){ 
      var view = new app.ContactView({model: contact}); 
      this.$('#contact-list').append(view.render().el); 
     }, 
     render: function(){ 
      this.$el.html(this.template()); 
      this.$('#contact-list').empty(); 
      for (var i = 0, l = this.model.models.length; i < l; i++) { 
      this.renderOne(this.model.models[i]); 
      } 
     }, 
     changeTheme: function(event){ 
      event.preventDefault(); 

      var theme = $(event.target).children("option").filter(":selected").text(); 

      changeTheme(theme); 
     }, 
     newContact: function(){ 
      app.router.navigate('/new', true); 
      return false; 
     } 
     }); 

     //Define the Application Router 
     app.Router = Backbone.Router.extend({ 
     routes: { 
      "": "contacts", 
      "contacts":"contacts", 
      "new": "newContact", 
      ":id": "contact" 
     },   
     contacts: function() { 
      var contactsCollection = new app.ContactsCollection(); 
      $.mobile.loading("show", { text: 'Loading Contacts', textVisible: true }); 
      contactsCollection.fetch({success: function(){ 
      $.mobile.loading("hide"); 
      $("#contacts-content").html(new app.ContactsView({model: contactsCollection}).el); 
      // Let jQuery Mobile do its stuff 
      $("#contacts-content").trigger('create'); 
      $.mobile.changePage("#contacts" , { reverse: false, changeHash: false }); 
      }}); 
     }, 
     contact: function(id) { 
      var contact = new app.Contact({Id: id}); 
      $.mobile.loading("show", { text: 'Loading Contact', textVisible: true }); 
      contact.fetch({success: function(){ 
      $.mobile.loading("hide"); 
      $("#contact-content").html(new app.ContactDetailView({model: contact}).el); 
      $("#contact-content").trigger('create'); 
      $.mobile.changePage("#contact" , { reverse: false, changeHash: false }); 
      }}); 
     }, 
     newContact: function(id) { 
      var contact = new app.Contact(); 
      $("#contact-content").empty(); 
      $("#contact-content").html(new app.ContactDetailView({model: contact}).el); 
      $("#contact-content").trigger('create'); 
      $.mobile.changePage("#contact" , { reverse: false, changeHash: false }); 
     } 
     }); 

     app.router = new app.Router(); 
     Backbone.history.start(); 
    } 
    </script> 

</body> 
</apex:page> 

Antwort

0

Sie können Visualforce Remote Objects für den Zugriff auf beliebige SObjects von JS verwenden. Zum Beispiel können Sie einige Objekte auf Visual Seite

<apex:remoteObjects > 
    <apex:remoteObjectModel name="Warehouse__c" jsShorthand="Warehouse" fields="Name,Id"> 
     <apex:remoteObjectField name="Phone__c" jsShorthand="Phone"/> 
    </apex:remoteObjectModel> 
</apex:remoteObjects> 

Und dann arbeiten mit diesen Objekten direkt in JavaScript definieren:

<script> 
    fetchWarehouses = function(){ 
     // Create a new Remote Object 
     var wh = new SObjectModel.Warehouse(); 

     // Use the Remote Object to query for 10 warehouse records 
     wh.retrieve({ limit: 10 }, function(err, records){ 
      if(err) alert(err.message); 
      else { 
       var ul = document.getElementById("warehousesList"); 
       records.forEach(function(record) { 
        // Build the text for a warehouse line item 
        var whText = record.get("Name"); 
        whText += " -- "; 
        whText += record.get("Phone"); 

        // Add the line item to the warehouses list 
        var li = document.createElement("li"); 
        li.appendChild(document.createTextNode(whText)); 
        ul.appendChild(li); 
       }); 
      } 
     }); 
    }; 
</script> 

Weitere Informationen SF documentation sehen.