2016-03-29 2 views
0

Мне удастся получить поля «Контакт» на странице visualforce, используя backbone.js. Я хочу показывать как поля учетной записи, так и поля контакта одновременно и на одной странице. Для этого следует использовать две модели для каждого объекта или две коллекции для каждого объекта. Если да, то, пожалуйста, объясните немного. Пожалуйста, направляйте меня, поскольку я новичок в backbone.js. Вот мой код.Salesforce: Как получить поля двух объектов «Учетная запись» и «Контакт» на странице visualforce с помощью 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> 

ответ

0

Вы можете использовать VisualForce Remote Objects для доступа к любым SObjects из JS. Например, вы можете определить некоторые объекты на странице Visualforce

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

И затем работать с этими объектами прямо в JavaScript:

<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> 

Для получения дополнительной информации см SF documentation.

Смежные вопросы