DevOps

解决Ghost升级到3.18.1后无法启动问题

起因

好久没登上服务器,一上班手贱上去运行了一把ghost update,升级到ghost 3.18.1,结果在重启ghost服务时就卡住了,转了老半天没有结果。手工启动ghost报错。放狗搜了一番,说是Nodejs版本太低的原因。上ghost官网查了兼容列表,确实是推荐使用nodejs v12。于是升级nodejs,再升级了ghost-cli,但是ghost服务还是没法成功启动。

解决方法

开始想偷懒,想着大不了强制升级一次。于是运行强制升级命令。

ghost update --force

结果连升级都报错。

运行ghost doctor,诊断结果报unknown error。

没有办法,尝试直接ghost run,发现网站可以运行,但是会报一个错。

WARN Can't connect to the bootstrap socket (localhost 8000) ECONNREFUSED

打开ghost配置文件config.production.json,发现有一节bootstrap-socket的配置内容。备份配置文件,把该节内容整个删除。

 

重启ghost,服务恢复正常。

安装Oracle JET Core Extension for VSCode

2019年5月20日,Oracle发布了JET 7.0.1版本,同时释出了JET Core Extension for VSCode Beta版。作为VS Code重度用户的俺来说,当然是第一时间下来尝鲜了。

因为是Beta版,该扩展并没有正式发布在VS Code Marketplace,需要在OTN下载手动安装。俺在MAC下用Chrome下载后,发现扩展程序安装文件扩展名为zip,VS Code并没不能辨认,尝试把文件扩展名手工改为VSIX,但在MAC下VS Code还是没能认出是扩展程序(ps:大概是文件权限的问题,但是找到了新方法,就没有去试)。

无意中发现使用Safari在OTN下载文件是正常的VSIX扩展名,后来在Oracle社区发现有人在讨论此问题,说Chrome会自动把文件扩展改为zip,换成Firefox或Edge下载就正常。

打开VS Code,点开左边扩展图标,点右上角的 “…” 打开更多操作菜单,选择“从VSIX安装…”。

 

选择下载的oracle-jet-core-0.5.0.vsix文件,安装JET Core Extension for VSCode。好了,现在可以体验JET的智能提醒和自动完成功能了。

解决Jdeveloper 12C(12.2.1.3.0) CreateProcess error=206问题

已经有阵子没用Jdev写东西了,因一个客户项目,周末打开Jdeveloper写了个Web Service客户端的Java示例程序。驾轻就熟从WSDL生成客户端代码,写了Impl实现,运行测试却碰到了问题,系统提示了以下文件名或扩展名过长的错误信息:

The target .jpr cannot be started because an exception was thrown: java.io.IOException: Cannot run program “C:\Java\jdk1.8.0_121\bin\javaw.exe” (in directory “C:\\src\”): CreateProcess error=206, The filename or extension is too long

仔细看了下错误信息,大概是因为库文件的原因,以下列方式解决:

打开项目属性窗口,把自动引用的JAX-WS Client和JAX-WS Web Service删除掉。

菜单Tools—–>Manage Libraries…

点击New,新建一个名为“ My JAX-WS Client ”用户库,点击“Add Entry”,选择
<JDev安装目录>\wlserver\server\lib\weblogic.jar
<JDev安装目录>\oracle_common\modules\internal\features\jrf_wlsFmw_oracle.jrf.wls.classpath.jar
点OK确认。

重复上面操作,新建立名为“ My JAX-WS Web Service ”的用户库,加入
<JDev安装目录> \wlserver\server\lib\weblogic.jar
点击OK确认。

回到项目属性窗口,加入刚创建的两个用户库,再次Run JAVA代码,成功运行。

后来空了查了下Oracle Support,发现这个问题是Jdeveloper 12.2.1.3.0的一个bug,官方已经有补丁程序释出,具体可以参考Running a Java Class Fails With “CREATEPROCESS ERROR=206” (Doc ID 2330982.1)。

Windows 10安装Netbeans 8.2出现错误msvcr100.dll+0x36adf解决办法

一直习惯用Sublime里写代码,最近为了调试几个JET程序,想装个Netbeans 8.2,结果运行安装程序时,却出现一个奇怪的错误。

问题描述


启动Netbeans安装程序,第一个窗口出来后就闪退,在安装程序目录下生成一个名字为“hs_err_pidxxxx.log”的文件,提示有致命错误。信息如下:



#
# Failed to write core dump. Minidumps are not enabled by default on client versions of Windows
#
# If you would like to submit a bug report, please visit:
# http://bugreport.java.com/bugreport/crash.jsp
# The crash happened outside the Java Virtual Machine in native code.
# See problematic frame for where to report the bug.
#


--------------- T H R E A D ---------------


Current thread (0x000000001921b800): JavaThread "Swing-Shell" daemon [_thread_in_native, id=6636, stack(0x000000001a1e0000,0x000000001a2e0000)]


siginfo: ExceptionCode=0xc0000005, reading address 0x0000000000000000


Registers:
RAX=0x0000000000000000, RBX=0x000000001a2df130, RCX=0x0000000000000000, RDX=0x0000000000cc8700
RSP=0x000000001a2df0d8, RBP=0x000000001a2df2c0, RSI=0x00000000000000e0, RDI=0x000000001921b9f8
R8 =0x0000000000cc8700, R9 =0x0000000000000000, R10=0x0000000000000000, R11=0x000000001a2dc2f0
R12=0x0000000000000000, R13=0x000000001a2df2e0, R14=0x000000001a2df2a8, R15=0x000000001921b800
RIP=0x0000000056926adf, EFLAGS=0x0000000000010246
......

然后安装程序自动退出。

解决方法


放狗搜了下,有人说是因为升级到最新版本的Win10所致。但经俺自己试验,其实系统上有God Folder导致,不管是God Folder是存在C盘还是桌面。把God Folder暂时挪至回收站,重新安装Netbeans,顺利完成。

Jdeveloper错误: Deployer:[149140]The task cannot be processed further until the current edit session is activated.

当想把WebCenter Space扩展程序发布至WebCenter Portal 12c时出现这个错误。

[Deployer:149140]The task cannot be processed further until the current edit session is activated.

 

space-error

 

原因

The user is the current owner of the domain configuration edit lock.

解决方法

Activate (or cancel) the edit session. The user can exit the deployer tool without affecting the task.

说成人话就是重启管理服务器或者在开发机器上把Default Domain删除了再重建即可解决。

 

Oracle JET的安装及配置

1. Oracle JET是什么鬼

按官方的说法,Oracle JET是给JavaScript开发者提供云端数据可视化的工具。JET使用了很多第三方的JavaScript库,例如jQuery,jQueryUI,Knockout,RequireJS和Hammer(如果在本地运行,需要Node.js支持)。

按俺的理解,JET就是O记把一堆前端工具整合到一起的大杂汇,让对前端框架不是特别熟的程序猿媛们能有一个快速开发响应式前端页面的路子。JET可以用于WEB页面开发,也可用于APP的开发。

JET的架构是这样的(基于MVVM设计模式)

Architecture

从官方的示例程序来看,JET做出来的页面效果还是不错的。

Workbetter

2. 对Oracle JET的看法

其实,开始的时候俺对Oracle JET的态度本来是抗拒的,认为没必要再重复造一个轮子。

wechatjet

个人对于知乎上这个问题的回答深以为然。

zhihujet

不过最近没有啥新东西玩,加上想在一些项目上看看能否把JET引进来(毕竟还是有些基于O记产品的项目), 于是报了官网上一个在线的JET Training,对着官方的文档安装环境。

 

3. 在Windows系统上安装JET

Oracle官网上的步骤已经很详细,基本上照着示例步骤安装即可完成。JET提供两种安装方式(或者称之为JET应用生成方式),一种是前端狗熟悉的Yeoman生成方式,一是使用Netbeans IDE引入JET包的方式(在这时深深鄙视O记一把,居然不把自家JDeveloper的支持做出来,使得如果要用JET与ADF应用结合的话必须使用两个IDE进行开发)。

3.1 以Yeoman方式安装

1).首先安装Git

下载Git Windows客户端,按提示完成安装。

2). 安装Node.js

前面提过,要在本地上运行JET必须Node.js支持,下载Windows下包含npm的Node.js安装包

downloadnode

进行Node.js的安装。

installnode1

 

installnode2

 

installnode3

稳定版的Node.js带的npm版本过低,我们需要升级npm,运行命令npm install –g npm进行升级。完成后用npm -v确认npm版本。

npmver

3). 安装Yeoman, Grunt, Bower工具包

运行命令npm –g install o bower grunt-cli,安装所需的工具包。

npmtool1

npmtool2

4). 安装JET Yeoman生成器

运行命令npm -g install generator-oraclejet

jetgenerator

5).基于模板生成第一个JET Web应用

运行命令yo oraclejet firstjet  –template=basic生成第一个JET Web应用。

firstjet1

firstjet2

应用生成成功后,用grunt生成并启动应用。

grunt build

grunt serve

firstjet3

访问本地服务地址,可以看到第一个JET应用的界面。

firstjet4

3.2 用Netbeans进行JET应用开发

1).安装Netbeans

Netbeans站点下载合适的安装包,进行Netbeans安装。

downloadnetbeans

netbeans1

 

2).下载Oracle JET压缩包

OTN下载JET压缩包oraclejet.zip并保存。

jetdownload

3)在Netbean创建Oracle JET应用

打开Netbean,新建一个HTML5/JavaScript应用程序。

newproject1

下一步选择项目位置。

newproject2

下一步,选择之前下载的OracleJET压缩包为模板来源,点下一步。选择你所需的工作,点完成,完成OracleJET应用的创建。

newproject4

温馨提示:如果你在天朝,安装支持包时,请注意科学上网

在Vultr的CentOS系统安装NodeJS和Express

最近迷上了基于MEAN的开发,加上寒假在给邱小姐做HTML+CSS+JS的培训,小朋友强烈要求弄一台服务器,使她的学习成果可以在公网上展示给小伙伴们看。想到恰好在Vultr上有一台空余的服务器,于是趁春节前的空闲部署了CentOS并搭建一台测试的Web服务器。不想花太多时间教小朋友后端编程语言,所以打了JavaScript的主意,准备前后端处理都用JS搞掂,所以决定用Express+NodeJS来做Web服务器。

在Vultr上安装NodeJS和Express异常简单,基本上用Yum管理器就可以傻瓜式安装完。

1.下载最新版的Node.js

切换到临时目录,用curl从Joylent直接下载最新版本的Node.js.

 cd /tmp 
curl -sL https://rpm.nodesource.com/setup | bash -

如下图所示:

Download latest Node.js

2. 安装Node.js

按照提示用yum安装Node.js.

yum install -y nodejs

Install Node.js

3.安装NPM包管理工具(可选)

如果你以后想安装Node的addon包,建议安装NPM包管理工具。运行命令:

yum install gcc-c++ openssl-devel make

Install build toolsInstall build tools
4.更新NPM工具(可选)
如果运行NPM时提示NPM版本低,可以选择更新NPM,按提示运行命令:

npm -g install [email protected]

Update NPM tool
5.安装Express

用NPM从仓库中安装Express
npm install -g express-generator

Install Express
6.创建运行服务的非特权用户(建设)

 useradd 用户名 
passwd 用户名

创建后登出系统并用新建的用户名重新登录。

7.创建Express项目
 express expressproject 
cd expressproject 
npm install

Create Express Project
8.运行Express

运行Express,启动服务。

DEBUG=expressproject:* npm start

如果一切正常,会出现以下提示

> [email protected] start /home/用户名/expressproject

> node ./bin/www

 

Start Express

至此,你可用http://IP:3000访问到你的Web服务了,Node.js+Express的环境搭建完成了。

Run Express

PHPMailer发匿名邮件及Extension missing: openssl的解决

纯粹玩票的性质,因为有个朋友需要一个发匿名邮件的工具,自告奋勇说帮他写。本以为手到擒来的事,结果还是折腾了大半天才弄好。

因为服务器上跑着Wordpress,所以就图方便想着用PHPMailer来写。在Github上下了最新的PHPMailer库,照着示例轻而易举地把页面写出来,在本机上用自己网易的私人邮箱发送邮件成功。但换了公司部署在腾讯上的企业邮箱发送时,因为使用了SSL验证,出现了“Extension missing: openssl”的错误(如下图所示)。

Send

因为对PHP实在不熟,刚开始还以为是PHPMailer的SMTPSecure设置问题,查了Github上的文档发现就是tls或者ssl两种方式,转回来在PHP配置上找原因,发现只需要把php.ini的extension=php_openssl.dll扩展开打,邮件即可发送成功。

不过当真的想发匿名邮件时,却又碰到一个问题,几乎所有邮件服务厂商都不支持设置Mail的From属性与登录的发件人不一样,发送时会报“MAIL FROM command failed,mail from address must be same as authorization user”的错误。无法可施,只能场外求助,还好付老板帮大力支持帮俺架了一个邮件服务器,终于可以在12点前交货,帮朋友发出匿名邮件了。

 

[转]jQuery背景的人该怎么看AngularJS

Original shared by Josh David Miller at http://stackoverflow.com/questions/14994391/how-do-i-think-in-angularjs-if-i-have-a-jquery-background/15012542?sgp=2#15012542

在stackoverflow上看到一则很好的关于jQuery背景的人该怎么看AngularJS,忍不住转过来。

1. Don’t design your page, and then change it with DOMmanipulations

In jQuery, you design a page, and then you make it dynamic. This is because jQuery was designed for augmentation and has grown incredibly from that simple premise.

But in AngularJS, you must start from the ground up with your architecture in mind. Instead of starting by thinking “I have this piece of the DOM and I want to make it do X”, you have to start with what you want to accomplish, then go about designing your application, and then finally go about designing your view.

2. Don’t augment jQuery with AngularJS

Similarly, don’t start with the idea that jQuery does X, Y, and Z, so I’ll just add AngularJS on top of that for models and controllers. This is really tempting when you’re just starting out, which is why I always recommend that new AngularJS developers don’t use jQuery at all, at least until they get used to doing things the “Angular Way”.

I’ve seen many developers here and on the mailing list create these elaborate solutions with jQuery plugins of 150 or 200 lines of code that they then glue into AngularJS with a collection of callbacks and $applys that are confusing and convoluted; but they eventually get it working! The problem is that in most cases that jQuery plugin could be rewritten in AngularJS in a fraction of the code, where suddenly everything becomes comprehensible and straightforward.

The bottom line is this: when solutioning, first “think in AngularJS”; if you can’t think of a solution, ask the community; if after all of that there is no easy solution, then feel free to reach for the jQuery. But don’t let jQuery become a crutch or you’ll never master AngularJS.

3. Always think in terms of architecture

First know that single-page applications are applications. They’re not webpages. So we need to think like a server-side developer in addition to thinking like a client-side developer. We have to think about how to divide our application into individual, extensible, testable components.

So then how do you do that? How do you “think in AngularJS”? Here are some general principles, contrasted with jQuery.

The view is the “official record”

In jQuery, we programmatically change the view. We could have a dropdown menu defined as a ul like so:

<ul class="main-menu">
    <li class="active">
        <a href="#/home">Home</a>
    </li>
    <li>
        <a href="#/menu1">Menu 1</a>
        <ul>
            <li><a href="#/sm1">Submenu 1</a></li>
            <li><a href="#/sm2">Submenu 2</a></li>
            <li><a href="#/sm3">Submenu 3</a></li>
        </ul>
    </li>
    <li>
        <a href="#/home">Menu 2</a>
    </li>
</ul>

In jQuery, in our application logic, we would activate it with something like:

$('.main-menu').dropdownMenu();

When we just look at the view, it’s not immediately obvious that there is any functionality here. For small applications, that’s fine. But for non-trivial applications, things quickly get confusing and hard to maintain.

In AngularJS, though, the view is the official record of view-based functionality. Our ul declaration would look like this instead:

<ul class="main-menu" dropdown-menu>
    ...
</ul>

These two do the same thing, but in the AngularJS version anyone looking at the template knows what’s supposed to happen. Whenever a new member of the development team comes on board, she can look at this and then know that there is a directive called dropdownMenu operating on it; she doesn’t need to intuit the right answer or sift through any code. The view told us what was supposed to happen. Much cleaner.

Developers new to AngularJS often ask a question like: how do I find all links of a specific kind and add a directive onto them. The developer is always flabbergasted when we reply: you don’t. But the reason you don’t do that is that this is like half-jQuery, half-AngularJS, and no good. The problem here is that the developer is trying to “do jQuery” in the context of AngularJS. That’s never going to work well. The view isthe official record. Outside of a directive (more on this below), you never, ever, never change the DOM. And directives are applied in the view, so intent is clear.

Remember: don’t design, and then mark up. You must architect, and then design.

Data binding

This is by far one of the most awesome features of AngularJS and cuts out a lot of the need to do the kinds of DOM manipulations I mentioned in the previous section. AngularJS will automatically update your view so you don’t have to! In jQuery, we respond to events and then update content. Something like:

$.ajax({
  url: '/myEndpoint.json',
  success: function ( data, status ) {
    $('ul#log').append('<li>Data Received!</li>');
  }
});

For a view that looks like this:

<ul class="messages" id="log">
</ul>

Apart from mixing concerns, we also have the same problems of signifying intent that I mentioned before. But more importantly, we had to manually reference and update a DOM node. And if we want to delete a log entry, we have to code against the DOM for that too. How do we test the logic apart from the DOM? And what if we want to change the presentation?

This a little messy and a trifle frail. But in AngularJS, we can do this:

$http( '/myEndpoint.json' ).then( function ( response ) {
    $scope.log.push( { msg: 'Data Received!' } );
});

And our view can look like this:

<ul class="messages">
    <li ng-repeat="entry in log">{{ entry.msg }}</li>
</ul>

But for that matter, our view could look like this:

<div class="messages">
    <div class="alert" ng-repeat="entry in log">
        {{ entry.msg }}
    </div>
</div>

And now instead of using an unordered list, we’re using Bootstrap alert boxes. And we never had to change the controller code! But more importantly, no matter where or how the log gets updated, the view will change too. Automatically. Neat!

Though I didn’t show it here, the data binding is two-way. So those log messages could also be editable in the view just by doing this: <input ng-model="entry.msg" />. And there was much rejoicing.

Distinct model layer

In jQuery, the DOM is kind of like the model. But in AngularJS, we have a separate model layer that we can manage in any way we want, completely independently from the view. This helps for the above data binding, maintains separation of concerns, and introduces far greater testability. Other answers mentioned this point, so I’ll just leave it at that.

Separation of concerns

And all of the above tie into this over-arching theme: keep your concerns separate. Your view acts as the official record of what is supposed to happen (for the most part); your model represents your data; you have a service layer to perform reusable tasks; you do DOM manipulation and augment your view with directives; and you glue it all together with controllers. This was also mentioned in other answers, and the only thing I would add pertains to testability, which I discuss in another section below.

Dependency injection

To help us out with separation of concerns is dependency injection (DI). If you come from a server-side language (from Java to PHP) you’re probably familiar with this concept already, but if you’re a client-side guy coming from jQuery, this concept can seem anything from silly to superfluous to hipster. But it’s not. 🙂

From a broad perspective, DI means that you can declare components very freely and then from any other component, just ask for an instance of it and it will be granted. You don’t have to know about loading order, or file locations, or anything like that. The power may not immediately be visible, but I’ll provide just one (common) example: testing.

Let’s say in our application, we require a service that implements server-side storage through a REST API and, depending on application state, local storage as well. When running tests on our controllers, we don’t want to have to communicate with the server – we’re testing the controller, after all. We can just add a mock service of the same name as our original component, and the injector will ensure that our controller gets the fake one automatically – our controller doesn’t and needn’t know the difference.

Speaking of testing…

4. Test-driven development – always

This is really part of section 3 on architecture, but it’s so important that I’m putting it as its own top-level section.

Out of all of the many jQuery plugins you’ve seen, used, or written, how many of them had an accompanying test suite? Not very many because jQuery isn’t very amenable to that. But AngularJS is.

In jQuery, the only way to test is often to create the component independently with a sample/demo page against which our tests can perform DOM manipulation. So then we have to develop a component separately and then integrate it into our application. How inconvenient! So much of the time, when developing with jQuery, we opt for iterative instead of test-driven development. And who could blame us?

But because we have separation of concerns, we can do test-driven development iteratively in AngularJS! For example, let’s say we want a super-simple directive to indicate in our menu what our current route is. We can declare what we want in the view of our application:

<a href="/hello" when-active>Hello</a>

Okay, now we can write a test for the non-existent when-active directive:

it( 'should add "active" when the route changes', inject(function() {
    var elm = $compile( '<a href="/hello" when-active>Hello</a>' )( $scope );

    $location.path('/not-matching');
    expect( elm.hasClass('active') ).toBeFalsey();

    $location.path( '/hello' );
    expect( elm.hasClass('active') ).toBeTruthy();
}));

And when we run our test, we can confirm that it fails. Only now should we create our directive:

.directive( 'whenActive', function ( $location ) {
    return {
        scope: true,
        link: function ( scope, element, attrs ) {
            scope.$on( '$routeChangeSuccess', function () {
                if ( $location.path() == element.attr( 'href' ) ) {
                    element.addClass( 'active' );
                }
                else {
                    element.removeClass( 'active' );
                }
            });
        }
    };
});

Our test now passes and our menu performs as requested. Our development is both iterative and test-driven. Wicked-cool.

5. Conceptually, directives are not packaged jQuery

You’ll often hear “only do DOM manipulation in a directive”. This is a necessity. Treat it with due deference!

But let’s dive a little deeper…

Some directives just decorate what’s already in the view (think ngClass) and therefore sometimes do DOM manipulation straight away and then are basically done. But if a directive is like a “widget” and has a template, it should also respect separation of concerns. That is, the template too should remain largely independent from its implementation in the link and controller functions.

AngularJS comes with an entire set of tools to make this very easy; with ngClass we can dynamically update the class; ngBind allows two-way data binding; ngShow and ngHide programmatically show or hide an element; and many more – including the ones we write ourselves. In other words, we can do all kinds of awesomeness without DOM manipulation. The less DOM manipulation, the easier directives are to test, the easier they are to style, the easier they are to change in the future, and the more re-usable and distributable they are.

I see lots of developers new to AngularJS using directives as the place to throw a bunch of jQuery. In other words, they think “since I can’t do DOM manipulation in the controller, I’ll take that code put it in a directive”. While that certainly is much better, it’s often still wrong.

Think of the logger we programmed in section 3. Even if we put that in a directive, we still want to do it the “Angular Way”. It still doesn’t take any DOM manipulation! There are lots of times when DOM manipulation is necessary, but it’s a lot rarer than you think! Before doing DOM manipulation anywhere in your application, ask yourself if you really need to. There might be a better way.

Here’s a quick example that shows the pattern I see most frequently. We want a toggleable button. (Note: this example is a little contrived and a skosh verbose to represent more complicated cases that are solved in exactly the same way.)

.directive( 'myDirective', function () {
    return {
        template: '<a class="btn">Toggle me!</a>',
        link: function ( scope, element, attrs ) {
            var on = false;

            $(element).click( function () {
                if ( on ) {
                    $(element).removeClass( 'active' );
                }
                else {
                    $(element).addClass( 'active' );
                }

                on = !on;
            });
        }
    };
});

There are a few things wrong with this:

  1. First, jQuery was never necessary. There’s nothing we did here that needed jQuery at all!
  2. Second, even if we already have jQuery on our page, there’s no reason to use it here; we can simply use angular.element and our component will still work when dropped into a project that doesn’t have jQuery.
  3. Third, even assuming jQuery was required for this directive to work, jqLite (angular.element) willalways use jQuery if it was loaded! So we needn’t use the $ – we can just use angular.element.
  4. Fourth, closely related to the third, is that jqLite elements needn’t be wrapped in $ – the element that is passed to the link function would already be a jQuery element!
  5. And fifth, which we’ve mentioned in previous sections, why are we mixing template stuff into our logic?

This directive can be rewritten (even for very complicated cases!) much more simply like so:

.directive( 'myDirective', function () {
    return {
        scope: true,
        template: '<a class="btn" ng-class="{active: on}" ng-click="toggle()">Toggle me!</a>',
        link: function ( scope, element, attrs ) {
            scope.on = false;

            scope.toggle = function () {
                scope.on = !scope.on;
            };
        }
    };
});

Again, the template stuff is in the template, so you (or your users) can easily swap it out for one that meets any style necessary, and the logic never had to be touched. Reusability – boom!

And there are still all those other benefits, like testing – it’s easy! No matter what’s in the template, the directive’s internal API is never touched, so refactoring is easy. You can change the template as much as you want without touching the directive. And no matter what you change, your tests still pass.

w00t!

So if directives aren’t just collections of jQuery-like functions, what are they? Directives are actuallyextensions of HTML. If HTML doesn’t do something you need it to do, you write a directive to do it for you, and then use it just as if it was part of HTML.

Put another way, if AngularJS doesn’t do something out of the box, think how the team would accomplish it to fit right in with ngClick, ngClass, et al.

Summary

Don’t even use jQuery. Don’t even include it. It will hold you back. And when you come to a problem that you think you know how to solve in jQuery already, before you reach for the $, try to think about how to do it within the confines the AngularJS. If you don’t know, ask! 19 times out of 20, the best way to do it doesn’t need jQuery and to try to solve it with jQuery results in more work for you.

Oracle ADF Mobile学习笔记 1:开发环境的安装及配置

这篇文章主要描述Oracle ADF Mobile开发环境的搭建工作。由于还没有测试过在window下搭建IOS的开发环境,所以此次只是描述JDeveloper的环境配置和Android开发环境搭建。

Android开发环境搭建

1.下载SDK

访问:http://developer.android.com/sdk/index.html ,下载SDK 。

 

无标题

根据我们的开发环境下载32位或64位。此处我们下载的是64位的SDK(adt-bundle-windows-x86_64-20140321.zip)。

2.安装SDK

将下载的zip文件解压到某个目录(不要中文、不要空格)。运行其目录下的SDK Manager.exe。参照下面的图示将相关选项选中(注意要将下方的Obsolete选中)。

选择需要安装的组件后按“Install packages”按钮进行安装。

无标题无标题

3.配置虚拟机

安装完成可以创建虚拟机。选择“Tools” — > “Manage AVDs”。开启虚拟机创建页面。

点击“New”按钮,创建虚机。如下图所示:

无标题1

无标题

点击“Start”按钮即可启动虚机。虚机启动后如下图。

无标题3

 

JDeveloper环境配置

1.安装JDeveloper

请安装11.1.2.4.0版本,安装JDeveloper不再描述

2.安装ADF Mobile插件

启动JDeveloper,选择Help–>Check for Updates,找到Oracle ADF Mobile,进行安装。目前最新版本如下:

无标题

 

3.配置JDeveloper

选择Tools –>Preferences。如下图配置Android的相关信息。

无标题

注意第三栏灰色的部分“Android Build Tools Location”,请选择正确的地址(早期的安卓版本在sdk/platform-tools下)。

 

至此开发环境搭建完成,在下一篇教程中我们将制作一个简单的APP应用。