Skip to content

zh

常見的 npm 權限問題

問題:

如果你正在使用Mac,並且通過從官方網站下載的pkg文件安裝了Node.js,那麼當你嘗試全局安裝一個npm模塊時,你可能會遇到以下的錯誤信息:

npm ERR! 請嘗試以root /管理員身份再次運行此命令。

我的解決方案:

不要用sudo命令來安裝包!

sudo npm install module -g

有些人在Stack Overflow上推薦上述解決方案,但我強烈建議不要用sudo來管理包。這種解決方案可能會暫時解決你的問題,但你將可能會在以後遇到更多問題。

下面是推薦的做法:

步驟1:使用以下命令確定你的用戶名:

whoami

例如,我的用戶名是victorleungtw。

步驟2:更改node模塊文件夾的擁有權:

sudo chown -R `whoami` /usr/local/lib/node_modules

執行這些步驟後,你將來在安裝npm包時就不必再使用sudo了。

Sublime Text 3:使用 OS X 命令列

問題

Sublime Text 3 包括一個命令行工具, subl。 不幸的是,當你在 OS X Yosemite 上安裝了編輯器後,這個工具無法直接工作。

我的解決方法

安裝Sublime Text 3後,使用以下命令創建一個符號鏈接:

ln -s /Applications/Sublime\ Text.app/Contents/SharedSupport/bin/subl /usr/local/bin/subl

在這裡,

  • /Applications/Sublime\ Text.app/Contents/SharedSupport/bin/subl 是應用程式在您的應用程式目錄中的存放位置。
  • /usr/local/bin 是您希望符號鏈接存在的選擇路徑。

要將Sublime Text設置為各種命令的默認編輯器,該命令提示輸入,請按照如下方式配置您的 EDITOR 環境變量:

export EDITOR='subl -w'

-w 標誌確保 subl 命令在文件關閉之前不會退出。

另外,您可以使用此命令將Sublime Text設置為您的默認Git編輯器:

git config --global core.editor "subl -n -w"

你需要知道的關於ECMAScript 6的12件事

ECMAScript 6 是 JavaScript 標準的下一個版本。

以下是您需要知道的有關 ES6 的12個酷事:

1. 箭頭函數

類似於 CoffeeScript,ES6 允許你使用肥箭頭語法定義一個函數。

var square = n => n * n

2. 箭頭範疇

‘this’關鍵字可能會令人困惑,因為它指的是調用它的東西。例如,當使用 setTimeout 時,‘this’ 指的是窗口物件。箭頭函數表達式解決了這個問題,將‘this’綁定到函數本身。

function yo() {
  this.name = "Victor"
  setTimeout(() => {
    console.log("yo " + this.name)
  }, 5000)
}
// Output: yo Victor

3. 字串模板

就像 CoffeeScript 一樣,ES6 包含了一個使用 ${} 語法用於變數的字串內插特性。注意下面的例子在第 2 行使用了反勾號而非單引號。

var person = { name: "Victor", age: 24 }
var hello = `My name is ${person.name} and I am ${person.age} years old`

4. Let 範疇

let 聲明了一個區塊範疇的本地變數。換句話說,它不會覆寫外部範疇中的變數值。

var x = 10
for (let i = 0; i < 10; i++) {
  let x = i * 2
}
console.log(x) // x is still 10, not 18

5. 陣列解構賦值

您不必逐一聲明多個變數,可以像這樣在一行中賦值給它們:

var [one, two, three] = [1, 2, 3]

6. 物件解構賦值

同樣地,您也可以為物件使用解構賦值:

var { firstName: name } = { firstName: "Victor" }

7. 物件字面量

您可以使用簡寫符號來構造一個物件,而不是寫 {firstName: firstName, lastName: lastName}

var firstName = "Victor",
  lastName = "Leung"
var person = { firstName, lastName }

8. 默認參數

您可以像這樣為參數分配默認值:

function sayHello(name, greeting = "yo man") {
  return `${greeting} ${name}`
}

9. 展開運算符

展開運算符(...)允許您將一個陣列的每個元素作為參數傳遞。

function threeNumbers(x, y, z) {
  console.log(x, y, z) // 0, 1, 2
}
var args = [0, 1, 2]
threeNumbers(...args)

10. 類別

就像其他物件導向的程式設計語言一樣,ES6 允許您使用新的類別語法來定義一個用於構建物件的藍圖。

class Person {
  sayHey(name) {
    return "hey " + name
  }
}

11. 類別繼承

您可以使用 extends 關鍵字來擴展一個類別。

class Victor extends Person {
  sayHey() {
    return super.sayHey("Victor")
  }
}

12. 產生器

產生器是可以被退出並稍後重新進入的函數。調用一個產生器函數並不會立即執行其內容。當迭代器的 next() 方法被調用時,產生器函數的內容會被執行,直到遇到第一個 yield 表達式。

function* idMaker() {
  var index = 0
  while (true) yield index++
}

var gen = idMaker()

console.log(gen.next().value) // 0
console.log(gen.next().value) // 1
console.log(gen.next().value) // 2

ECMAScript 6中有許多新特性。更多細節,請參考 MDN。官方發表過程於2015年3月在Mozilla開始,並預計於2015年6月完成。敬請期待!

我對Hack Reactor遠程Beta的評價

我參加了在香港的第二屆Hack Reactor Remote Beta,以提高我的JavaScript技術技能。

該課程結構嚴謹,提供了許多優秀的講座和先進技術的實戰經驗。

我從學習遞歸,閉包,和數據結構開始。一旦我對基礎有了堅實的掌握,我就轉向學習各種JavaScript框架,包括BackboneJS, AngularJS, 和 NodeJS,所有這些都是由各自領域的專家教導。為了完成課程,我進行了多個項目,這些項目讓我全面接觸到像ThreeJS和ReactJS這樣的新工具。對於我的論文項目,我建立了一個機器學習服務器來推薦啤酒,這既有挑戰性又很有趣。

與其他遠程學生的協作是一種非常有價值的經驗。我們密切合作,使用Floobits進行配對編程,並使用Google Hangouts進行每日站立會議。員工在HipChat上非常活躍,並且總是熱衷於提供幫助。講師們非常擅長教學,即使你不是電腦科學專業的人,他們也能使複雜的主題變得容易理解。我感謝他們為提供這種高質量的遠程課程而付出的努力。

我強烈推薦這個課程給任何對編程感興趣的人。它提供了五星級的學習體驗。

使用PredictionIO的啤酒推薦引擎

問題:

我們都愛啤酒。然而,今天我們面臨的是前所未有的選擇多樣性,讓我們感到不知所措和猶豫不決:我們下一個該喝什麼?

我的解決方案:

在我們的Hack Reactor論文計畫中,我構建了一個使用PredictionIO作為啤酒推薦引擎的機器學習服務器。廣義地說,該應用基於兩個主要策略:

  1. 內容過濾方法:這使用每種啤酒的各種特性來識別其性質。例如,我們利用breweryDB來確定特定啤酒的風格,其酒精度(ABV)和其國際苦味單位(IBU)。然後我們查詢數據庫以找到風格相似的啤酒。

  2. 協同過濾方法:這完全依賴於過去的用戶行為,特別是你的啤酒評級。它使用交替最小二乘法(ALS)算法的矩陣因子分解技術。我們通過從啤酒評級模式中推斷出來的因子向量來描述啤酒和用戶。啤酒和用戶因子之間的高度相關性將導致推薦。

使用矩陣因子分解的一個優點是其能夠加入附加資訊。當沒有顯性反饋(即,你的評級)時,我們可以使用隱性反饋,如你的瀏覽歷史和搜尋模式,來推斷出用戶偏好。

結果,OnTapp將你和適合你口味的啤酒配對起來。要獲得啤酒推薦並嘗試我們的示例,請訪問:http://ontappapp.com/.

AngularUI:處理Google地圖標記的滑鼠懸停事件

問題:

我花了一些時間才弄清楚這個問題,所以我覺得這個問題值得一篇自己的博客文章。當我試著用AngularUI連接Google Map標記的滑鼠懸停事件時,我發現自己很困惑。文件在這件事情上很含糊,說它只支援單一標記,而不支援多個標記。

對於單一標記,只需要在HTML中指定一個帶有 events 屬性的指令就很直接:

<ui-gmap-marker events="marker.events"></ui-gmap-marker>

然後在控制器中:

$scope.marker = {
  events: {
    mouseover: function (marker, eventName, args) {
      // 回調代碼在此
    },
  },
}

然而,相同的做法不適用於多個標記。我最初以為我可以簡單地為每個標記添加滑鼠懸停事件,就像這樣:

markers.push({
  events: {
    mouseover: function (mapModel, eventName, originalEventArgs) {
      console.log("I'd really like to show the info window on mouseover.")
    },
  },
})

我的解決方案:

為了解決這個問題,將以下內容添加到HTML markers 指令:

events="clickEventsObject"

並在控制器中:

$scope.clickEventsObject = {
  mouseover: markerMouseOver,
  mouseout: markerMouseOut,
}

function markerMouseOver(marker, e) {
  // 回調代碼在此
}

function markerMouseOut(marker, e) {
  // 回調代碼在此
}

它成功了!這個處理程序返回一個直接映射的模型陣列,該陣列屬於與事件一起發送的gMarker集群。如果你有任何問題,請隨時向我提問。😊

找出2015年新年決心的竅門

當一年即將結束,新的一年在1月1日開始時,許多人會設定新年決心。然而,92%的新年決心最終都會失敗。為什麼會這樣?

這個問題引起了我的興趣。以我的黑客思維,我喜歡將問題解決技巧應用到各種情況中,如果能突破這8%的成功率,我會非常高興。

研究顯示,'意志力'可能是一種有限的資源。我們都渴望改進自己,但僅靠意志力往往不足以達成目標。未能達成我們的目標可能會讓人沮喪,導致一種自我批評的循環,這並不幫助我們前進。

要產生有意義的變化,我們需要保持我們的目標既簡單又可實現。解決手邊易於應對的問題,可以提供繼續前進的動力。將模糊的抱負轉化為具體的目標並每天為之努力是很重要的。畢竟,我們是我們重複行動的總和。因此,卓越更多的是一種習慣,而非孤立的行為。

我的年度目標

為保持自己在正軌上,我制定了每日待辦事項,包括:

  1. 始終保持編程- 每天至少花一個小時解決玩具問題或接受編程挑戰。

  2. 優先考慮身體健康 - 每天花30分鐘慢跑或做其他運動。 健康的身體養育健康的心靈。

  3. 致力於學習- 每天花一個小時閱讀書籍或觀看教育影片,擴展你的知識。

  4. 加強社交網絡- 每天花一個小時和家人或朋友聯繫,無論是在午餐,晚餐,或一次簡單的聊天。

Angular.js 工廠:異步處理 $http

問題:

當我使用 $http 服務從遠程API獲取數據時,下面的代碼片段無法將數據返回到控制器。

myApp.factory("myFactory", function ($http) {
  var data = { anArray: [] }

  $http.get("/api").success(function (response) {
    data.anArray.push(response)
  })

  return data
})

這個問題的出現是因為在 $http GET請求將數據推送到數組之前,就執行了 return 語句。

我的解決方案:

為了異步處理數據,當數據被接收到時,控制器需要指導服務採取什麼行動:

myApp.factory("myFactory", function ($http) {
  return {
    getData: function () {
      return $http.get("/api")
    },
  }
})

myApp.controller("MyController", [
  "$scope",
  "myFactory",
  function ($scope, myFactory) {
    $scope.data = []

    var handleSuccess = function (response, status) {
      $scope.data = response
    }

    myFactory.getData().success(handleSuccess)
  },
])

如果你有任何問題,請讓我知道。😊

使用Express設置代理伺服器

問題:

我正在進行一個使用BreweryDB的項目。在嘗試從API加載一些數據時,我遇到一個問題:該API不支援JSONP。當我試圖直接使用Angular獲取數據時,會導致CORS問題:

XMLHttpRequest無法加載[https://api.brewerydb.com/v2/.](https://api.brewerydb.com/v2/)。請求的資源上沒有'Access-Control-Allow-Origin'頭。因此,不允許“http://localhost:3000”的來源訪問。

我的解決方案:

為了避免暴露我的API密鑰,我需要設置一個中間代理。以下是使用Node.js和Express設置代理的步驟說明。

步驟1:安裝Express和Request

npm install express --save
npm install request --save

步驟2:建立一個 server.js 檔案

var express = require('express');
var request = require('request');
var app = express();

步驟3:設定路由(將 API_KEY 換成你實際的API密鑰)

app.get('/api', function(req, res) {
  request('https://api.brewerydb.com/v2/?key=' + API_KEY, function (error, response, body) {
    if (!error && response.statusCode === 200) {
      console.log(body);
      res.send(body);
    }
  });
});

步驟4:設定埠口

app.listen(3000);
console.log('伺服器在埠口%d運行', 3000);

步驟5:啟動伺服器(node server.js

開啟你的瀏覽器,導航到 http://localhost:3000/api 。你應該能看到JSON物件並且在你的瀏覽器控制台中將其記錄下來:

"message": "請求成功",
"data": "您已到達BreweryDB.com API。對於訪問,請查看http://www.brewerydb.com/developers",
"status": "成功"

如果您遇到任何問題,請隨時向我發送電子郵件。☺

Angular UI Bootstrap:使用ng-repeat開啟第一個手風琴

問題:

我在使用Angular UI Bootstrap版本0.1.2的手風琴指令。在示例頁面上,有一個範例顯示如何默認開啟第一個手風琴組:

<accordion-group heading="First Header" is-open="true"> </accordion-group>

這對於靜態內容來說工作得很好,但是對於使用ng-repeat生成的動態內容來說,它無法如預期地操作。換句話說,它不能這樣工作:

<accordion-group
  heading="{{group.title}}"
  ng-repeat="group in groups"
  is-open="true"
>
</accordion-group>

我的解決方案:

在模板中,將手風琴的is-open屬性綁定如下:

<accordion-group
  heading="{{group.title}}"
  ng-repeat="group in groups"
  is-open="status.isItemOpen[$index]"
>
</accordion-group>

並在控制器中:

$scope.groups = ["First Header", "Second Header", "Third Header"]
$scope.status = {
  isItemOpen: new Array($scope.groups.length),
  isFirstDisabled: false,
}
$scope.status.isItemOpen[0] = true

如果你希望第一個手風琴默認為關閉,則將最後一行的值改為false

如果這個解決方案對你沒有作用,請讓我知道。😊