将AngularJS与Liferay一起使用

标记

我将在Liferay Portal中使用全局AngularJS。因为,就像AngularJS的设计一样:

为什么选择AngularJS?HTML非常适合于声明静态文档,但是当我们尝试使用它来声明Web应用程序中的动态视图时,HTML却显得毫无用处。AngularJS允许您扩展应用程序的HTML词汇。由此产生的环境具有极强的表现力,可读性,并且可以快速开发。

通过开发Liferay-Theme和Portlet,我将简单地使用html的声明性语法。

为此,我创建了新的Liferay主题并自定义了以下内容portal_normal.vm

<!DOCTYPE html>

<#include init />

<html ... ng-app="liferay">
<head>
        ...
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.8/angular.min.js"></script>
    <script type="text/javascript" src="${javascript_folder}/my.js" charset="utf-8"></script>
</head>
<body class="${css_class}">
    <div ng-controller="LiferayCtrl">

在这里my.js

angular.module('liferay', [])

.controller('LiferayCtrl', function($scope) {
    console.log("---==== Init AngularJS ====---");
    $scope.Liferay = Liferay;
});

而且我可以扩展控制器,例如获得Liferay-Site名称。

这一切是为了什么?

因此,我可以通过声明性html语法简单地访问Liferay JavaScript值和函数,而无需像AngularJS那样直接调用JavaScript函数。

例如,现在可以通过声明性的html代码来获取Liferay JavaScript的值和功能,例如此处,以在Web内容显示中获取当前的url:

Liferay current URL: {{Liferay.currentURL}}

在此处输入图片说明

但是,我的问题是:

  • 在Liferay中使用AngularJS会产生哪些副作用?
  • 会出现性能问题吗?
  • 与其他JavaSripts(例如Alloy)冲突?
  • 在Portlet中使用AngularJS?
迈克尔

首先:在门户网站上使用AngularJS的好主意。到目前为止,我们仅将AngularJS用于portlet –我将在后面解释原因和方式。

可能的副作用和冲突

与其他JavaScript库或框架一样,使用AngularJS不会产生更多副作用。Liferay随AlloyUi(http://alloyui.com/一起提供该JavaScript库基于yahoo编写的YUI(http://yuilibrary.com/)。YUI使用的名称空间不同于jQuery,因此您可以将jQuery与AlloyUI一起使用。而且,如果您能够使用jQuery而没有任何副作用,则可以使用AngularJS,因为AngularJS提供了jQuery的一个子集。

如果您不仅需要AngularJS的jqLit​​e实现,还需要完整的jQuery,则只需确保在AngularJS之前包含jQuery。可以通过更改portal_normal.vm主题中的来轻松完成此操作

<head>
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
    <title>$the_title - $company_name</title>
    <script type="text/javascript" src="$javascript_folder/jquery-2.0.3.min.js" charset="utf-8"></script>
    <script type="text/javascript" src="$javascript_folder/angular-1.2.7.min.js" charset="utf-8"></script>
    $theme.include($top_head_include)
</head>

如果在主题级别包含JavaScript文件,则可以为每个主题使用不同的版本。如果您有多个门户网站实例,并且没有机会在每个实例中使用相同的版本,则这非常方便。

性能

这取决于。必须知道,如果将ng-app指令放在html元素上,Angular将解析整个网页,如您的示例。如果您的页面很大,并且内容很多,则可能是性能问题。因此,最好将ngApp指令放到页面的下方,并通过以下方式手动初始化ngApp:

$().ready(function() {
    angular.bootstrap("css-selector", ['yourApp']);
});

在Portlet中使用AngularJS

有两种方法可以实现此目的。

1)在您的示例中,在大ngApp上。您必须知道,您不能嵌套ngApps。因此,每个portlet必须是您应用程序的一部分。使用这种方法,您将失去Portlet可以为页面提供单独部分的可能性。所有portlet需要知道ngApp的名称,并且必须扩展此ngApp。如果这些portlet使用其他ngApp名称或不使用任何其他ngApp名称,则不得在未更改其他门户网站服务器的情况下使用它们。其优点是可以共享$rootScope所有的门户和门户可以与角度的方式相互通信(例如$emit$on共享servcies,...)。

2)每个portlet都有自己的ngApp。在这种情况下,没有依赖性。每个portlet都可以通过实例化其自己的ngApp angular.bootstrap此外,每个ngApp只会为一小部分网页创建,只有在确实需要时才创建。

两种方式都应避免使用路由。因为routeProvider每页只能使用一个

我们已决定使用第二种方法,以使Portlet保持独立并且不依赖于全局ngApp。

有用的提示–我希望

Portlet配置

您知道可以配置您的portlet。因此出现了一个问题:“我该如何为我的有角度的portlet提供我的portlet首选项?” 当然,您可以发出http请求以获取它们。但这还不够,因为您拨打了不必要的电话。您的Portlet通常是Java服务器页面,因此最好在服务器的生成时间中包含首选项,并将这些信息提供给您的角度应用程序。但是如何?

doViewportlet方法中,您可以创建一个JSON对象并将其存储在您的密钥中RenderRequest

public void doView(RenderRequest renderRequest, RenderResponse renderResponse) throws IOException, PortletException {
    PortletPreferences prefs = renderRequest.getPreferences();

    Map<String, Object> values = new HashMap<String, Object>();
    values.put(key, value);

    renderRequest.setAttribute("config", new ObjectMapper().writeValueAsString(values));

    super.doView(renderRequest, renderResponse);
}

在您的jsp中,您可以访问以下配置属性:

<div class="hidden" portlet-config>${config}</div>

portlet-config 是解析JSON并将信息存储在服务实例中的指令:

.factory('portletConfigService', function(){ return {}})

.directive('portletConfig', ['portletConfigService', function(portletConfigService) {
    return {
        restrict: 'A',
        compile: function(elem, attrs) {
            var config = angular.fromJson(elem.text());
            angular.forEach(config, function(value, key){
                portletConfigService[key] = value;
            });
        }
    };
}])

现在,您可以将注入portletConfigService到每个控制器,服务,工厂或其他任何东西,并使用config参数:portletConfigService.key

语言属性

我们遇到的另一个问题是语言属性。通常,您将在language.properties文件中定义它们,并在jsp中使用它们。例如通过fmt:message标签。但是您还希望能够在您的angular js应用程序中访问它们。而且,您绝对不希望在源中将它们包含两次。我们通过生成的服务和一条指令来解决此问题,该指令读取当前用户语言的属性并在jsp中创建有角度的东西:

<%@page contentType="text/javascript; charset=UTF-8" %>
<%@ page import="java.util.ResourceBundle" %>
<%@ page import="java.util.Locale" %>
<%@ page import="java.util.Enumeration" %>
<%@ page import="org.apache.commons.lang.StringEscapeUtils" %>
angular.module('translations', [])
.factory('translations', function(){ return {
<%
    ResourceBundle labels =  ResourceBundle.getBundle("language", request.getLocale());
    Enumeration<String> keys = labels.getKeys();
    while(keys.hasMoreElements()){
        String key = keys.nextElement();
        out.write("\""+key+"\":\""+StringEscapeUtils.escapeJavaScript(labels.getString(key))+"\"");
        if(keys.hasMoreElements()){
            out.write(",\n");
        }
    }
%>
}}) 

.filter('mpbtranslate', ['translations', function(translations) { 
    return function(input) { 
        var translation = translations[input];
        return translation? translation: '???'+input+'???'; 
    }; 
}]);

现在,您可以将这些翻译用作服务和过滤器。例如,<div>{{'title' | translate}}</div>将在客户端被评估为“ Titel”。

希望您得到有关您所关注问题的有用信息。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

将effekt与angularjs一起使用

来自分类Dev

将AngularJS与npm一起使用

来自分类Dev

将OpenLayers与RequireJS和AngularJS一起使用

来自分类Dev

将Angularjs ngBind与javascript对象一起使用

来自分类Dev

强制特定页面将HTTPS与angularjs一起使用

来自分类Dev

将Wijmo事件日历与angularjs一起使用

来自分类Dev

AngularJS:将$ routeProvider与多个模块一起使用?

来自分类Dev

将库(Plyr)与指令和AngularJS一起使用

来自分类Dev

将angularjs $ timeout与$ scope的“ this”一起使用

来自分类Dev

我如何将ajax与angularJS一起使用?

来自分类Dev

将库(Plyr)与指令和AngularJS一起使用

来自分类Dev

我如何将 AngularJs 与 JsBarcode 一起使用?

来自分类Dev

Django不与Angularjs一起使用

来自分类Dev

使AngularJS与AWS DynamoDB一起使用

来自分类Dev

使AngularJS与AWS DynamoDB一起使用

来自分类Dev

我可以在liferay 6.1中将最新版本的YUI与AUI一起使用吗?

来自分类Dev

将“ -Filter”与变量一起使用

来自分类Dev

将PowerMock与黄瓜一起使用

来自分类Dev

将XhtmlTextWriter与XmlTextReader一起使用

来自分类Dev

将Scrapyd与参数一起使用

来自分类Dev

将Magicline与Flexslider一起使用

来自分类Dev

将CMAttitude与CMCalibratedMagneticField一起使用

来自分类Dev

将findall与arg一起使用

来自分类Dev

将StaticPagedList与PagedListRenderOptions一起使用

来自分类Dev

将Redis与SignalR一起使用

来自分类Dev

将阵列与渗透一起使用

来自分类Dev

将ctypes与typedef一起使用

来自分类Dev

将regex与replaceAll一起使用

来自分类Dev

将SUMPRODUCT与TRANSPOSE一起使用