Angular JS指令在visualforce(salesforce)中不起作用

Angular JS directives doesn’t work in visualforce(salesforce)?

本文关键字:salesforce 不起作用 visualforce JS 指令 Angular      更新时间:2023-09-26

>在视觉力页面(作为容器)中,我在角度JS中创建了一个自定义指令,但它不起作用。事实上,该指令甚至没有被调用!虽然这在JSFiddle中工作得很好

下面是自定义指令。当我在 HTML 标记中使用此指令时,它永远不会在控制台日志上显示任何内容。我创建了多个指令并看到了相同的行为。我相信在 visualforce 容器中使用自定义指令时存在错误。你们中有人遇到过同样的问题吗?任何帮助将不胜感激。

谢谢!-党卫军

更新

这是自定义指令的 JSFiddle 可以正常工作,但是当我在视觉力页面中使用它时,它不起作用。(即使指令具有控制台.log控制台中也不会显示任何内容。这证明没有调用指令)http://jsfiddle.net/ssah13/3y1z5943/

请注意:此指令去除了 OppName 中下划线之前和之后的所有内容。例如:如果 OppName 为 "111111_Test_123445",则输出为 "Test"

这是视觉力页面和一个控制器:

页:

<apex:page docType="html-5.0" controller="SalesActions">
  <head>
    <script src="//code.jquery.com/jquery-1.11.0.min.js"/>
    <apex:includeScript value="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.8/angular.min.js"/>
  </head>
        <!-- HTML FOR APP -->
        <!-- To use bootstrap with visualforce everything needs to be wrapped with "bs" class-->
        <div ng-app="salesApp" class="bs">
          <div ng-controller="salesController">
              <div ng-repeat="sfResult in salesforceResponse">
                <table>
                  <tr ng-repeat="opp in sfResult.opportunities">
                    <td>
                      <span opp-name="" input="opp.Name">
                          {{opp.Name}}
                      </span>
                    </td>
                  </tr>
                </table>
              </div>
          </div>
        </div>
      <!-- ACTUAL ANGULAR JS APP : Later on move this to salesworkspace.js-->
    <script type = "text/javascript">
      var ngApp = angular.module('salesApp', []);
      //Opp Name directive
      ngApp.directive('oppName', function () {
          return {
              restrict: 'A',
              scope: {
                  input: '='
              },
              link: function (scope, element, attrs) {
                 console.log('Input: ', scope.input);
                  var input = scope.input;
                  if (!input) {
                      return;
                  }
                  // AccountName_Test_123445
                  if (input.indexOf('_')) {
                      scope.input = input.split('_')[1];
                  }
              }
          };
      });
        ngApp.controller('salesController', ['$scope',
            function($scope) {
                  $scope.salesforceResponse = [];
                  Visualforce.remoting.Manager.invokeAction(
                      '{!$RemoteAction.SalesActions.getAllAccounts}',
                      function(result, event) {
                          if (event.status) {
                            $scope.$apply(function() {  //Use Apply as the scope changed outside Angular Context?
                             $scope.salesforceResponse = result;
                              console.log($scope.salesforceResponse);
                              });
                           } else {
                            console.log(event);
                          }
                        }
                  );
        } //End of function
      ]); //End of Controller method
  </script>
  </apex:page>

控制器:salesActions.cls

public with sharing class SalesActions {
    public SalesActions() { } // empty constructor
    @RemoteAction
    public static List<accountWrapper> getAllAccounts() {
        List<accountWrapper> accountResponse = new List<accountWrapper>();
        List<account> accs = [SELECT Id, Name, Type, Strategic_Account_Management__c,
                                    (SELECT Id FROM Opportunities) ,
                                    (SELECT Name FROM Contacts)
                              FROM Account
                              Order by Name]; //Add a Filter here. WHERE ownerId = :Userinfo.getUserId();
        Set<Id> accountIds = new Set<Id>();
        for(account acc : accs) {
            accountIds.add(acc.Id);
        }
        Map<Id,Opportunity> oppIdToOpp = new Map<Id,Opportunity>([
                                                SELECT Id,Name, Account.Name, Agency__r.Name, Campaign_EVENT__c,Rate_Type__c,StageName,Amount,CurrencyISOCode,
                                                       Probability,CampaignStartDate2__c,CampaignEndDate2__c,Contact__c,Sales_Notes__c,
                                                (SELECT SplitAmount, SplitOwner.Name,SplitPercentage, Split__c FROM OpportunitySplits)
                                                 FROM Opportunity WHERE AccountId IN :accountIds]// Remove WHERE AccountId =:accountId and Add WHERE account.ownerId=:UserInfo.getId();
                                                 );

        Map<Id,List<Partner>> accountIdToPartners = new Map<Id,List<Partner>>();
        for(Partner p :[SELECT AccountFromId,AccountTo.Name FROM Partner WHERE AccountFromId IN :accountIds]) {
            if(accountIdToPartners.containsKey(p.AccountFromId)) {
                accountIdToPartners.get(p.AccountFromId).add(p);
            } else {
                accountIdToPartners.put(p.AccountFromId, new List<Partner>{p});
            }
        }
        for(Account acc : accs) {
            accountWrapper accWrapper = new accountWrapper();
            accWrapper.account = acc; // This will add all the accounts and related contacts
            accWrapper.opportunities = new List<Opportunity>();
            accWrapper.partners = new list<Partner>();
            if(accountIdToPartners.containsKey(acc.Id)){
                accWrapper.partners = accountIdToPartners.get(acc.Id);
            }
            for(Opportunity opp : acc.Opportunities) {
                accWrapper.opportunities.add(oppIdToOpp.get(opp.Id));  // This will add all the opportunties and opportunitySplits
            }
            accountResponse.add(accWrapper);
        }
        return accountResponse;
    }
    public class accountWrapper {
        public Account account { get; set; }
        public List<Partner> partners { get; set; }
        public List<Opportunity> opportunities { get; set; }
    }
}
对我来说,

这就是我让它工作的方式:

ngApp.directive('testDirective', function () {
  return {
    restrict: 'E',
    scope: {
        input: '='
    },
    template: '<p>{{input}}</p>',
    link: function (scope, element, attrs) {
       console.log('Input: ', scope.input);
        var input = scope.input;
        if (!input) {
            return;
        }
        // AccountName_Test_123445
        if (input.indexOf('_') !== -1) {
            scope.input = input.split('_')[1];
        }
      }
    };
  });

然后在 HTML 中:

<test-directive input="opp.Name"></test-directive>

这些只是一些小的变化。不完全确定为什么它以前在 VF 中不起作用。在 VF 中,我总是尝试使用指令作为元素,因为 VF 不能像普通 HTML 那样具有这些空属性。然后,您应该在指令中定义模板或模板Url。(您也可以在此处使用 VF 页面作为模板 - 即使触发标准控制器或自定义控制器!

哦,当然,再次看看ngRemote,因为它可以帮助您在VF上使用AngularJS应用程序。

希望这有帮助!

佛瑞恩